apertur

package module
v0.1.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 13, 2026 License: MIT Imports: 23 Imported by: 0

README

apertur-go

Official Go SDK for the Apertur API. Collect photos from any mobile device via QR codes — no app required.

Installation

go get github.com/Apertur-dev/apertur-go

Requires Go 1.21 or later. No external dependencies.

Quick Start

package main

import (
	"context"
	"fmt"
	"os"

	apertur "github.com/Apertur-dev/apertur-go"
)

func main() {
	client := apertur.New(apertur.Config{APIKey: "aptr_xxxx"})
	ctx := context.Background()

	// Create a session and upload an image
	session, err := client.Sessions.Create(ctx, apertur.CreateSessionOptions{
		Tags: []string{"demo"},
	})
	if err != nil {
		panic(err)
	}

	f, _ := os.Open("./photo.jpg")
	defer f.Close()

	result, err := client.Upload.Image(ctx, session.UUID, f, apertur.UploadOptions{})
	if err != nil {
		panic(err)
	}
	fmt.Printf("Uploaded: %s (%d bytes)\n", result.Filename, result.SizeBytes)
}

Authentication

Two auth methods: API key (for server-to-server) and OAuth token (for third-party integrations).

// API Key — environment auto-detected from prefix
client := apertur.New(apertur.Config{APIKey: "aptr_your_key_here"})

// Test/sandbox key
client := apertur.New(apertur.Config{APIKey: "aptr_test_your_key_here"})

// OAuth Token
client := apertur.New(apertur.Config{OAuthToken: "your_oauth_token"})

// Custom base URL (for self-hosted or staging)
client := apertur.New(apertur.Config{
	APIKey:  "aptr_xxx",
	BaseURL: "https://custom.api.example.com",
})

See Authentication documentation

Sessions

Create upload sessions, check status, and manage password-protected sessions.

ctx := context.Background()

// Create a session
longPolling := true
maxImages := 50
expiresIn := 48
session, err := client.Sessions.Create(ctx, apertur.CreateSessionOptions{
	Tags:           []string{"event-photos"},
	ExpiresInHours: &expiresIn,
	MaxImages:      &maxImages,
	Password:       "secret123",
	LongPolling:    &longPolling,
})

// Get session info
info, err := client.Sessions.Get(ctx, session.UUID)

// Update a session
newMax := 100
_, err = client.Sessions.Update(ctx, session.UUID, apertur.UpdateSessionOptions{
	MaxImages: &newMax,
})

// List sessions (paginated)
page := 1
list, err := client.Sessions.List(ctx, apertur.ListParams{Page: &page})

// Get recent sessions
limit := 5
recent, err := client.Sessions.Recent(ctx, apertur.LimitParams{Limit: &limit})

// Verify password for protected sessions
result, err := client.Sessions.VerifyPassword(ctx, session.UUID, "secret123")

// Get QR code as PNG bytes
qr, err := client.Sessions.QR(ctx, session.UUID, apertur.QrOptions{
	Format: "png",
	Size:   300,
})

// Check delivery status (one-shot snapshot)
status, err := client.Sessions.DeliveryStatus(ctx, session.UUID)
// status.Status, status.Files, status.LastChanged

// Long-poll for changes (server holds up to 5 minutes; use a 6m context timeout)
pollCtx, cancel := context.WithTimeout(ctx, 6*time.Minute)
defer cancel()
next, err := client.Sessions.DeliveryStatus(pollCtx, session.UUID, apertur.DeliveryStatusOptions{
	PollFrom: status.LastChanged,
})

See Sessions documentation

Uploading Images

Upload images from any io.Reader. Supports optional server-side encryption.

// Upload from file
f, _ := os.Open("./photo.jpg")
defer f.Close()
result, err := client.Upload.Image(ctx, sessionUUID, f, apertur.UploadOptions{
	Filename: "vacation.jpg",
	MimeType: "image/jpeg",
	Source:   "gallery",
})

// Upload with server-side encryption
key, _ := client.Encryption.GetServerKey(ctx)
f2, _ := os.Open("./photo.jpg")
defer f2.Close()
result, err = client.Upload.ImageEncrypted(ctx, sessionUUID, f2, key.PublicKey, apertur.UploadOptions{})

See Upload documentation

Long Polling

Retrieve uploaded images via polling instead of webhooks. Requires a session created with LongPolling: true.

// Manual poll cycle
poll, err := client.Polling.List(ctx, sessionUUID)
for _, image := range poll.Images {
	data, err := client.Polling.Download(ctx, sessionUUID, image.ID)
	if err != nil { break }
	os.WriteFile("./downloads/"+image.Filename, data, 0644)
	client.Polling.Ack(ctx, sessionUUID, image.ID)
}

// Automatic poll + process loop (stops on context cancellation)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

err = client.Polling.PollAndProcess(ctx, sessionUUID, func(image apertur.PollImage, data []byte) error {
	fmt.Printf("Received: %s (%d bytes)\n", image.Filename, image.SizeBytes)
	return os.WriteFile("./output/"+image.Filename, data, 0644)
}, apertur.PollProcessOptions{Interval: 3})

// Stop polling from another goroutine
cancel()

See Long Polling documentation

Receiving Webhooks

Verify webhook signatures to ensure payloads are authentic. Three verification methods match the Apertur signature schemes.

import apertur "github.com/Apertur-dev/apertur-go"

// Image delivery webhook
isValid := apertur.VerifyWebhookSignature(bodyString, signatureHeader, webhookSecret)

// Event webhook (HMAC SHA256)
isValid = apertur.VerifyEventSignature(bodyString, timestampHeader, signatureHeader, eventSecret)

// Event webhook (Svix)
isValid = apertur.VerifySvixSignature(bodyString, svixID, svixTimestamp, svixSignature, eventSecret)

See Webhook documentation

Destinations

Manage delivery destinations (webhook, S3, Google Drive, etc.).

destinations, err := client.Destinations.List(ctx, projectID)

webhook, err := client.Destinations.Create(ctx, projectID, apertur.CreateDestinationConfig{
	Type: "webhook",
	Name: "My Backend",
	Config: map[string]interface{}{
		"url":    "https://api.example.com/photos",
		"format": "json_base64",
	},
})

testResult, err := client.Destinations.Test(ctx, projectID, webhook.ID)
_, err = client.Destinations.Update(ctx, projectID, webhook.ID, apertur.UpdateDestinationConfig{
	Name: "Updated Name",
})
err = client.Destinations.Delete(ctx, projectID, webhook.ID)

See Destinations documentation

API Keys

Manage API keys and their default destinations.

keys, err := client.Keys.List(ctx, projectID)

created, err := client.Keys.Create(ctx, projectID, apertur.CreateAPIKeyOptions{
	Label: "Production",
})
fmt.Printf("Save this key: %s\n", created.PlainTextKey) // Only shown once!

// Set default destinations for a key
longPolling := true
keyDests, err := client.Keys.SetDestinations(ctx, created.Key.ID, []string{dest1ID, dest2ID}, &longPolling)

See API Keys documentation

Event Webhooks

Subscribe to project events (uploads, deliveries, billing changes, etc.).

wh, err := client.Webhooks.Create(ctx, projectID, apertur.CreateEventWebhookConfig{
	URL:    "https://api.example.com/events",
	Topics: []string{"project.upload.*", "project.billing.plan_changed"},
})

// List deliveries
deliveries, err := client.Webhooks.Deliveries(ctx, projectID, wh.ID, apertur.WebhookDeliveriesOptions{})

// Retry a failed delivery
_, err = client.Webhooks.RetryDelivery(ctx, projectID, wh.ID, deliveries.Deliveries[0].ID)

See Event Webhooks documentation

Error Handling

All SDK errors implement the standard error interface. Use errors.As() for typed error handling.

import "errors"

session, err := client.Sessions.Get(ctx, "nonexistent")
if err != nil {
	var rateLimitErr *apertur.RateLimitError
	var authErr *apertur.AuthenticationError
	var notFoundErr *apertur.NotFoundError
	var validationErr *apertur.ValidationError
	var apiErr *apertur.AperturError

	switch {
	case errors.As(err, &rateLimitErr):
		fmt.Printf("Rate limited. Retry after: %ds\n", rateLimitErr.RetryAfter)
	case errors.As(err, &authErr):
		fmt.Println("Invalid API key")
	case errors.As(err, &notFoundErr):
		fmt.Println("Resource not found")
	case errors.As(err, &validationErr):
		fmt.Printf("Validation error: %s\n", validationErr.Message)
	case errors.As(err, &apiErr):
		fmt.Printf("API error %d: %s (code: %s)\n", apiErr.StatusCode, apiErr.Message, apiErr.Code)
	default:
		fmt.Printf("Unexpected error: %v\n", err)
	}
}

API Reference

For complete API documentation, visit docs.apertur.ca.

License

MIT

Documentation

Overview

Package apertur provides the official Go client for the Apertur API.

Apertur lets you collect photos from any mobile device via QR codes — no app required. This SDK wraps the REST API with idiomatic Go types, context-aware methods, and built-in error handling.

Create a client with New and access resources through the named fields:

client := apertur.New(apertur.Config{APIKey: "aptr_xxxx"})
session, err := client.Sessions.Create(ctx, apertur.CreateSessionOptions{})

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func VerifyEventSignature

func VerifyEventSignature(body, timestamp, signature, secret string) bool

VerifyEventSignature verifies an event webhook signature using HMAC SHA256. The signature header is expected in the format "sha256=<hex>". Calculation: HMAC-SHA256("${timestamp}.${body}", secret).

func VerifySvixSignature

func VerifySvixSignature(body, svixID, timestamp, signature, secret string) bool

VerifySvixSignature verifies an event webhook signature using the Svix method. The signature header is expected in the format "v1,<base64>". The secret must be hex-encoded. Calculation: HMAC-SHA256("${svixId}.${timestamp}.${body}", hex-decoded secret).

func VerifyWebhookSignature

func VerifyWebhookSignature(body, signature, secret string) bool

VerifyWebhookSignature verifies an image delivery webhook signature. The signature header is expected in the format "sha256=<hex>". Calculation: HMAC-SHA256(body, secret).

Types

type APIKey

type APIKey struct {
	ID                    string   `json:"id"`
	Prefix                string   `json:"prefix"`
	Label                 string   `json:"label"`
	Env                   string   `json:"env"`
	IsActive              bool     `json:"isActive"`
	LastUsedAt            *string  `json:"lastUsedAt"`
	MaxImages             *int     `json:"maxImages"`
	AllowedMimeTypes      []string `json:"allowedMimeTypes"`
	MaxImageDimension     *int     `json:"maxImageDimension"`
	LongPollingEnabled    bool     `json:"longPollingEnabled"`
	DefaultDestinations   []string `json:"defaultDestinations"`
	AllowedIPs            []string `json:"allowedIps"`
	AllowedDomains        []string `json:"allowedDomains"`
	TOTPEnabled           bool     `json:"totpEnabled"`
	ClientCertEnabled     bool     `json:"clientCertEnabled"`
	ClientCertFingerprint *string  `json:"clientCertFingerprint"`
	CreatedAt             string   `json:"createdAt"`
}

APIKey represents an API key resource.

type AckResult

type AckResult struct {
	Status string `json:"status"`
}

AckResult is the response from acknowledging a polled image.

type Apertur

type Apertur struct {
	// Env indicates the target environment, either "live" or "test".
	// It is inferred from the API key prefix unless BaseURL is overridden.
	Env string

	// Sessions provides operations on upload sessions.
	Sessions *SessionsResource
	// Upload provides image upload operations.
	Upload *UploadResource
	// Uploads provides listing operations for uploaded images.
	Uploads *UploadsResource
	// Polling provides long-polling operations to retrieve uploaded images.
	Polling *PollingResource
	// Destinations provides CRUD operations on delivery destinations.
	Destinations *DestinationsResource
	// Keys provides CRUD operations on API keys.
	Keys *KeysResource
	// Webhooks provides CRUD operations on event webhooks.
	Webhooks *WebhooksResource
	// Encryption provides access to server encryption keys.
	Encryption *EncryptionResource
	// Stats provides dashboard statistics.
	Stats *StatsResource
	// contains filtered or unexported fields
}

Apertur is the top-level client for the Apertur API. Construct one with New. All resource operations are accessed through the exported fields.

func New

func New(cfg Config) *Apertur

New creates a new Apertur client with the given configuration. The Config must include either an APIKey or OAuthToken; otherwise New panics.

The target environment is auto-detected from the key prefix: keys starting with "aptr_test_" target the sandbox, all others target the live API. Set Config.BaseURL to override this behaviour.

type AperturError

type AperturError struct {
	// StatusCode is the HTTP status code from the response.
	StatusCode int `json:"status_code"`
	// Code is the machine-readable error code from the API (e.g. "NOT_FOUND").
	Code string `json:"code"`
	// Message is the human-readable error description.
	Message string `json:"message"`
}

AperturError is the base error type for all API errors returned by the Apertur service.

func (*AperturError) Error

func (e *AperturError) Error() string

Error implements the error interface.

type AuthenticationError

type AuthenticationError struct {
	AperturError
}

AuthenticationError indicates a 401 Unauthorized response.

func NewAuthenticationError

func NewAuthenticationError(message string) *AuthenticationError

NewAuthenticationError creates an AuthenticationError with the given message.

type Config

type Config struct {
	// APIKey is the API key used for authentication (prefixed with "aptr_" or "aptr_test_").
	APIKey string
	// OAuthToken is an OAuth bearer token, used as an alternative to APIKey.
	OAuthToken string
	// BaseURL overrides the default API base URL. When empty, the URL is auto-detected
	// from the API key prefix: "aptr_test_" uses the sandbox, otherwise the live endpoint.
	BaseURL string
}

Config holds the configuration for the Apertur client.

type CreateAPIKeyOptions

type CreateAPIKeyOptions struct {
	Label             string   `json:"label"`
	MaxImages         *int     `json:"maxImages,omitempty"`
	AllowedMimeTypes  []string `json:"allowedMimeTypes,omitempty"`
	MaxImageDimension *int     `json:"maxImageDimension,omitempty"`
}

CreateAPIKeyOptions contains options for creating a new API key.

type CreateAPIKeyResult

type CreateAPIKeyResult struct {
	Key          APIKey `json:"key"`
	PlainTextKey string `json:"plainTextKey"`
}

CreateAPIKeyResult is the response from creating an API key. The PlainTextKey is only returned once and must be stored by the caller.

type CreateDestinationConfig

type CreateDestinationConfig struct {
	Type   string                 `json:"type"`
	Name   string                 `json:"name"`
	Config map[string]interface{} `json:"config"`
}

CreateDestinationConfig is the request body for creating a destination.

type CreateEventWebhookConfig

type CreateEventWebhookConfig struct {
	URL                  string            `json:"url"`
	Topics               []string          `json:"topics"`
	SignatureMethod      string            `json:"signatureMethod,omitempty"`
	MaxRetries           *int              `json:"maxRetries,omitempty"`
	RetryIntervals       []int             `json:"retryIntervals,omitempty"`
	DisableAfterFailures *int              `json:"disableAfterFailures,omitempty"`
	CustomHeaders        map[string]string `json:"customHeaders,omitempty"`
}

CreateEventWebhookConfig is the request body for creating an event webhook.

type CreateSessionOptions

type CreateSessionOptions struct {
	DestinationIDs    []string `json:"destination_ids,omitempty"`
	LongPolling       *bool    `json:"long_polling,omitempty"`
	Tags              []string `json:"tags,omitempty"`
	ExpiresInHours    *int     `json:"expires_in_hours,omitempty"`
	ExpiresAt         string   `json:"expires_at,omitempty"`
	MaxImages         *int     `json:"max_images,omitempty"`
	AllowedMimeTypes  []string `json:"allowed_mime_types,omitempty"`
	MaxImageDimension *int     `json:"max_image_dimension,omitempty"`
	Password          string   `json:"password,omitempty"`
}

CreateSessionOptions contains options for creating a new upload session.

type CreateSessionResult

type CreateSessionResult struct {
	UUID              string               `json:"uuid"`
	UploadURL         string               `json:"upload_url"`
	QRURL             string               `json:"qr_url"`
	QRSpecs           QrSpecs              `json:"qr_specs"`
	Destinations      []SessionDestination `json:"destinations"`
	LongPolling       bool                 `json:"long_polling"`
	ExpiresAt         string               `json:"expires_at"`
	PasswordProtected bool                 `json:"password_protected"`
	Env               string               `json:"env"`
}

CreateSessionResult is the response from creating an upload session.

type DeliveryDestinationStatus

type DeliveryDestinationStatus struct {
	DestinationID string  `json:"destination_id"`
	Type          string  `json:"type"`
	Name          string  `json:"name"`
	Status        string  `json:"status"`
	Attempts      int     `json:"attempts"`
	LastError     *string `json:"last_error"`
}

DeliveryDestinationStatus describes the delivery state for a single destination.

type DeliveryRecordStatus

type DeliveryRecordStatus struct {
	RecordID     string                      `json:"record_id"`
	Filename     string                      `json:"filename"`
	SizeBytes    int64                       `json:"size_bytes"`
	HasThumbnail bool                        `json:"has_thumbnail,omitempty"`
	Destinations []DeliveryDestinationStatus `json:"destinations"`
}

DeliveryRecordStatus describes the delivery state for a single uploaded image.

type DeliveryStatusOptions added in v0.1.5

type DeliveryStatusOptions struct {
	// PollFrom is an ISO 8601 timestamp. When set, the server will hold the
	// response for up to 5 minutes until the delivery state changes past this
	// cursor (new file, delivery transition, or session status change). Pass
	// the `LastChanged` value from a previous response to continue polling.
	//
	// Long-polling callers should pair this with a `context.Context` that has
	// at least a 6-minute deadline so the server releases the response first
	// under the happy path.
	PollFrom string
}

DeliveryStatusOptions contains optional parameters for the DeliveryStatus call.

type DeliveryStatusResponse added in v0.1.5

type DeliveryStatusResponse struct {
	Status      string                 `json:"status"`
	Files       []DeliveryRecordStatus `json:"files"`
	LastChanged string                 `json:"lastChanged"`
}

DeliveryStatusResponse is the response from the delivery-status endpoint. The API returns the overall session status, the per-file delivery states, and the timestamp of the most recent change (used as the `pollFrom` cursor for long-polling follow-up requests).

type Destination

type Destination struct {
	ID        string                 `json:"id"`
	Type      string                 `json:"type"`
	Name      string                 `json:"name"`
	Config    map[string]interface{} `json:"config"`
	IsActive  bool                   `json:"isActive"`
	CreatedAt string                 `json:"createdAt"`
	UpdatedAt string                 `json:"updatedAt"`
}

Destination represents a configured delivery destination.

type DestinationsResource

type DestinationsResource struct {
	// contains filtered or unexported fields
}

DestinationsResource provides CRUD operations on delivery destinations.

func (*DestinationsResource) Create

func (d *DestinationsResource) Create(ctx context.Context, projectID string, config CreateDestinationConfig) (*Destination, error)

Create adds a new destination to the project.

func (*DestinationsResource) Delete

func (d *DestinationsResource) Delete(ctx context.Context, projectID, destID string) error

Delete removes a destination from the project.

func (*DestinationsResource) List

func (d *DestinationsResource) List(ctx context.Context, projectID string) ([]Destination, error)

List returns all destinations for the given project.

func (*DestinationsResource) Test

func (d *DestinationsResource) Test(ctx context.Context, projectID, destID string) (*TestDestinationResult, error)

Test sends a test payload to the destination and returns the result.

func (*DestinationsResource) Update

func (d *DestinationsResource) Update(ctx context.Context, projectID, destID string, config UpdateDestinationConfig) (*Destination, error)

Update modifies an existing destination.

type EncryptedPayload

type EncryptedPayload struct {
	EncryptedKey  string `json:"encryptedKey"`
	IV            string `json:"iv"`
	EncryptedData string `json:"encryptedData"`
	Algorithm     string `json:"algorithm"`
}

EncryptedPayload holds the encrypted image data and wrapped key.

func EncryptImage

func EncryptImage(imageData []byte, publicKeyPEM string) (*EncryptedPayload, error)

EncryptImage encrypts image data using AES-256-GCM with a random key, then wraps the AES key using RSA-OAEP with the provided PEM-encoded public key. The returned EncryptedPayload contains all fields base64-encoded, ready to be sent to the Apertur API.

type EncryptionResource

type EncryptionResource struct {
	// contains filtered or unexported fields
}

EncryptionResource provides access to the server's encryption keys.

func (*EncryptionResource) GetServerKey

func (e *EncryptionResource) GetServerKey(ctx context.Context) (*ServerKey, error)

GetServerKey retrieves the server's public key used for end-to-end encryption.

type EventWebhook

type EventWebhook struct {
	ID                   string            `json:"id"`
	ProjectID            string            `json:"projectId"`
	URL                  string            `json:"url"`
	Secret               string            `json:"secret"`
	SignatureMethod      string            `json:"signatureMethod"`
	Topics               []string          `json:"topics"`
	IsActive             bool              `json:"isActive"`
	MaxRetries           int               `json:"maxRetries"`
	RetryIntervals       []int             `json:"retryIntervals"`
	DisableAfterFailures int               `json:"disableAfterFailures"`
	ConsecutiveFailures  int               `json:"consecutiveFailures"`
	CustomHeaders        map[string]string `json:"customHeaders"`
	DisabledAt           *string           `json:"disabledAt"`
	CreatedAt            string            `json:"createdAt"`
	UpdatedAt            string            `json:"updatedAt"`
}

EventWebhook represents an event webhook subscription.

type KeyDestinationEntry

type KeyDestinationEntry struct {
	ID       string `json:"id"`
	Type     string `json:"type"`
	Name     string `json:"name"`
	IsActive bool   `json:"isActive"`
}

KeyDestinationEntry describes a destination linked to a key.

type KeyDestinations

type KeyDestinations struct {
	Destinations       []KeyDestinationEntry `json:"destinations"`
	LongPollingEnabled bool                  `json:"longPollingEnabled"`
}

KeyDestinations is the response from setting destinations on a key.

type KeysResource

type KeysResource struct {
	// contains filtered or unexported fields
}

KeysResource provides CRUD operations on API keys.

func (*KeysResource) Create

func (k *KeysResource) Create(ctx context.Context, projectID string, opts CreateAPIKeyOptions) (*CreateAPIKeyResult, error)

Create generates a new API key for the project. The plain-text key is only available in the response and must be stored by the caller.

func (*KeysResource) Delete

func (k *KeysResource) Delete(ctx context.Context, projectID, keyID string) error

Delete removes an API key from the project.

func (*KeysResource) List

func (k *KeysResource) List(ctx context.Context, projectID string) ([]APIKey, error)

List returns all API keys for the given project.

func (*KeysResource) SetDestinations

func (k *KeysResource) SetDestinations(ctx context.Context, keyID string, destinationIDs []string, longPolling *bool) (*KeyDestinations, error)

SetDestinations configures the default destinations and long-polling setting for the given key. Pass nil for longPolling to leave the setting unchanged.

func (*KeysResource) Update

func (k *KeysResource) Update(ctx context.Context, projectID, keyID string, opts UpdateAPIKeyOptions) (*APIKey, error)

Update modifies an existing API key.

type LimitParams

type LimitParams struct {
	Limit *int `json:"limit,omitempty"`
}

LimitParams holds a limit parameter for "recent" endpoints.

type ListParams

type ListParams struct {
	Page     *int `json:"page,omitempty"`
	PageSize *int `json:"pageSize,omitempty"`
}

ListParams holds common pagination parameters.

type NotFoundError

type NotFoundError struct {
	AperturError
}

NotFoundError indicates a 404 Not Found response.

func NewNotFoundError

func NewNotFoundError(message string) *NotFoundError

NewNotFoundError creates a NotFoundError with the given message.

type PollImage

type PollImage struct {
	ID        string `json:"id"`
	Filename  string `json:"filename"`
	SizeBytes int64  `json:"size_bytes"`
	MimeType  string `json:"mime_type"`
	Source    string `json:"source"`
	CreatedAt string `json:"created_at"`
}

PollImage describes an image available for polling.

type PollProcessOptions

type PollProcessOptions struct {
	// Interval is the delay between poll cycles. Defaults to 3 seconds.
	Interval int
}

PollProcessOptions configures the PollAndProcess loop.

type PollResult

type PollResult struct {
	Images []PollImage `json:"images"`
}

PollResult is the response from the polling endpoint.

type PollingResource

type PollingResource struct {
	// contains filtered or unexported fields
}

PollingResource provides long-polling methods to retrieve uploaded images. Sessions must be created with LongPolling enabled.

func (*PollingResource) Ack

func (p *PollingResource) Ack(ctx context.Context, uuid, imageID string) (*AckResult, error)

Ack acknowledges that a polled image has been processed, removing it from subsequent poll results.

func (*PollingResource) Download

func (p *PollingResource) Download(ctx context.Context, uuid, imageID string) ([]byte, error)

Download retrieves the raw image bytes for a polled image.

func (*PollingResource) List

func (p *PollingResource) List(ctx context.Context, uuid string) (*PollResult, error)

List returns images that are available for download via polling.

func (*PollingResource) PollAndProcess

func (p *PollingResource) PollAndProcess(ctx context.Context, uuid string, handler func(image PollImage, data []byte) error, opts PollProcessOptions) error

PollAndProcess runs a continuous poll-download-ack loop until the context is cancelled. For each image found, handler is called with the image metadata and raw bytes. If handler returns an error, the loop stops and the error is returned. The default poll interval is 3 seconds.

type QrOptions

type QrOptions struct {
	Format      string `json:"format,omitempty"`
	Size        int    `json:"size,omitempty"`
	Style       string `json:"style,omitempty"`
	FG          string `json:"fg,omitempty"`
	BG          string `json:"bg,omitempty"`
	BorderSize  int    `json:"border_size,omitempty"`
	BorderColor string `json:"border_color,omitempty"`
}

QrOptions configures the QR code rendering.

type QrSpecs

type QrSpecs struct {
	Endpoint string            `json:"endpoint"`
	Formats  []string          `json:"formats"`
	Params   map[string]string `json:"params"`
}

QrSpecs describes the QR code endpoint and available parameters.

type RateLimitError

type RateLimitError struct {
	AperturError
	// RetryAfter is the number of seconds to wait before retrying, if provided by the server.
	RetryAfter int `json:"retry_after"`
}

RateLimitError indicates a 429 Too Many Requests response.

func NewRateLimitError

func NewRateLimitError(message string, retryAfter int) *RateLimitError

NewRateLimitError creates a RateLimitError with the given message and retry-after duration.

type ServerKey

type ServerKey struct {
	PublicKey string `json:"publicKey"`
}

ServerKey is the response from the encryption server-key endpoint.

type Session

type Session struct {
	ID                         string   `json:"id"`
	Status                     string   `json:"status"`
	ExpiresAt                  string   `json:"expiresAt"`
	Tags                       []string `json:"tags"`
	ImagesPerSession           *int     `json:"imagesPerSession"`
	EffectiveMaxImages         *int     `json:"effectiveMaxImages"`
	EffectiveAllowedMimeTypes  []string `json:"effectiveAllowedMimeTypes"`
	EffectiveMaxImageDimension *int     `json:"effectiveMaxImageDimension"`
	PasswordProtected          *bool    `json:"password_protected"`
	ServerPublicKey            string   `json:"serverPublicKey,omitempty"`
	E2EEnabled                 *bool    `json:"e2eEnabled,omitempty"`
	E2EPublicKey               *string  `json:"e2ePublicKey,omitempty"`
	E2EDowngraded              *bool    `json:"e2eDowngraded,omitempty"`
}

Session represents the state of an upload session.

type SessionDestination

type SessionDestination struct {
	ID   string `json:"id"`
	Type string `json:"type"`
	Name string `json:"name"`
}

SessionDestination describes a destination attached to a session.

type SessionRow

type SessionRow struct {
	ID                 string   `json:"id"`
	CreatedAt          string   `json:"createdAt"`
	ExpiresAt          string   `json:"expiresAt"`
	Status             string   `json:"status"`
	ProjectID          string   `json:"projectId"`
	ProjectName        string   `json:"projectName"`
	ImagesCount        int      `json:"imagesCount"`
	ImagesDelivered    int      `json:"imagesDelivered"`
	ImagesFailed       int      `json:"imagesFailed"`
	DestinationsCount  int      `json:"destinationsCount"`
	Tags               []string `json:"tags"`
	LongPollingEnabled bool     `json:"longPollingEnabled"`
	Label              *string  `json:"label"`
	Env                string   `json:"env"`
}

SessionRow is a summary row returned in session list endpoints.

type SessionsListPage

type SessionsListPage struct {
	Data       []SessionRow `json:"data"`
	Total      int          `json:"total"`
	Page       int          `json:"page"`
	PageSize   int          `json:"pageSize"`
	TotalPages int          `json:"totalPages"`
}

SessionsListPage is a paginated response of session rows.

type SessionsResource

type SessionsResource struct {
	// contains filtered or unexported fields
}

SessionsResource provides methods for managing upload sessions.

func (*SessionsResource) Create

Create creates a new upload session with the given options.

func (*SessionsResource) DeliveryStatus

func (s *SessionsResource) DeliveryStatus(ctx context.Context, uuid string, opts ...DeliveryStatusOptions) (*DeliveryStatusResponse, error)

DeliveryStatus returns the delivery status for all images in the session.

When opts.PollFrom is set to an ISO 8601 timestamp, the server long-polls for up to 5 minutes waiting for a change since that cursor. Callers that want to long-poll should ensure the supplied context has a timeout of at least 6 minutes (e.g. context.WithTimeout(ctx, 6*time.Minute)) so the server releases the response first under the happy path.

Pass zero or more DeliveryStatusOptions; only the first is used.

func (*SessionsResource) Get

func (s *SessionsResource) Get(ctx context.Context, uuid string) (*Session, error)

Get retrieves the state of an upload session by UUID.

func (*SessionsResource) List

List returns a paginated list of sessions.

func (*SessionsResource) QR

func (s *SessionsResource) QR(ctx context.Context, uuid string, opts QrOptions) ([]byte, error)

QR returns the QR code image bytes for the given session. The response format depends on the options (PNG, SVG, or JPEG).

func (*SessionsResource) Recent

func (s *SessionsResource) Recent(ctx context.Context, params LimitParams) ([]SessionRow, error)

Recent returns the most recently created sessions.

func (*SessionsResource) Update

func (s *SessionsResource) Update(ctx context.Context, uuid string, opts UpdateSessionOptions) (*Session, error)

Update modifies an existing upload session.

func (*SessionsResource) VerifyPassword

func (s *SessionsResource) VerifyPassword(ctx context.Context, uuid, password string) (*VerifyPasswordResult, error)

VerifyPassword checks whether the given password is valid for the session.

type SetKeyDestinationsRequest

type SetKeyDestinationsRequest struct {
	DestinationIDs     []string `json:"destination_ids"`
	LongPollingEnabled *bool    `json:"long_polling_enabled,omitempty"`
}

SetKeyDestinationsRequest is the request body for setting a key's destinations.

type Stats

type Stats struct {
	SessionsThisMonth   int               `json:"sessionsThisMonth"`
	SessionsTotal       int               `json:"sessionsTotal"`
	ImagesUploaded      int               `json:"imagesUploaded"`
	ImagesDelivered     int               `json:"imagesDelivered"`
	DeliverySuccessRate float64           `json:"deliverySuccessRate"`
	TotalProjects       int               `json:"totalProjects"`
	ActiveKeys          int               `json:"activeKeys"`
	TopProjects         []StatsTopProject `json:"topProjects"`
}

Stats holds dashboard-level statistics.

type StatsResource

type StatsResource struct {
	// contains filtered or unexported fields
}

StatsResource provides access to dashboard-level statistics.

func (*StatsResource) Get

func (s *StatsResource) Get(ctx context.Context) (*Stats, error)

Get retrieves the current dashboard statistics.

type StatsTopProject

type StatsTopProject struct {
	ID       string `json:"id"`
	Name     string `json:"name"`
	Sessions int    `json:"sessions"`
}

StatsTopProject describes a project with its session count.

type TestDestinationResult

type TestDestinationResult struct {
	Success bool    `json:"success"`
	Status  *int    `json:"status,omitempty"`
	Error   *string `json:"error,omitempty"`
	Message *string `json:"message,omitempty"`
}

TestDestinationResult is the response from testing a destination.

type UpdateAPIKeyOptions

type UpdateAPIKeyOptions struct {
	Label             string   `json:"label,omitempty"`
	IsActive          *bool    `json:"isActive,omitempty"`
	MaxImages         *int     `json:"maxImages,omitempty"`
	AllowedMimeTypes  []string `json:"allowedMimeTypes,omitempty"`
	MaxImageDimension *int     `json:"maxImageDimension,omitempty"`
	AllowedIPs        []string `json:"allowedIps,omitempty"`
	AllowedDomains    []string `json:"allowedDomains,omitempty"`
}

UpdateAPIKeyOptions contains fields that can be updated on an API key.

type UpdateDestinationConfig

type UpdateDestinationConfig struct {
	Name     string                 `json:"name,omitempty"`
	Config   map[string]interface{} `json:"config,omitempty"`
	IsActive *bool                  `json:"isActive,omitempty"`
}

UpdateDestinationConfig is the request body for updating a destination.

type UpdateEventWebhookConfig

type UpdateEventWebhookConfig struct {
	URL                  string            `json:"url,omitempty"`
	Topics               []string          `json:"topics,omitempty"`
	IsActive             *bool             `json:"isActive,omitempty"`
	MaxRetries           *int              `json:"maxRetries,omitempty"`
	RetryIntervals       []int             `json:"retryIntervals,omitempty"`
	DisableAfterFailures *int              `json:"disableAfterFailures,omitempty"`
	CustomHeaders        map[string]string `json:"customHeaders,omitempty"`
}

UpdateEventWebhookConfig is the request body for updating an event webhook.

type UpdateSessionOptions

type UpdateSessionOptions struct {
	ExpiresAt         string   `json:"expires_at,omitempty"`
	MaxImages         *int     `json:"max_images,omitempty"`
	AllowedMimeTypes  []string `json:"allowed_mime_types,omitempty"`
	MaxImageDimension *int     `json:"max_image_dimension,omitempty"`
	MaxImageSizeMB    *int     `json:"max_image_size_mb,omitempty"`
	Password          *string  `json:"password,omitempty"`
}

UpdateSessionOptions contains the fields that can be updated on a session.

type UploadDestinationBreakdown

type UploadDestinationBreakdown struct {
	Type  string `json:"type"`
	Count int    `json:"count"`
}

UploadDestinationBreakdown describes the count of deliveries per destination type.

type UploadOptions

type UploadOptions struct {
	Filename string
	MimeType string
	Source   string
	Password string
}

UploadOptions contains optional parameters for image uploads.

type UploadResource

type UploadResource struct {
	// contains filtered or unexported fields
}

UploadResource provides methods for uploading images to a session.

func (*UploadResource) Image

func (u *UploadResource) Image(ctx context.Context, uuid string, file io.Reader, opts UploadOptions) (*UploadResult, error)

Image uploads an image to the session identified by uuid. The file parameter is an io.Reader containing the image data. Use UploadOptions to set the filename, MIME type, source, and session password.

func (*UploadResource) ImageEncrypted

func (u *UploadResource) ImageEncrypted(ctx context.Context, uuid string, file io.Reader, publicKeyPEM string, opts UploadOptions) (*UploadResult, error)

ImageEncrypted uploads an image encrypted with the server's public key. The image data is read from file and encrypted using EncryptImage. The resulting envelope is sent as the bytes of a multipart "file" part with the X-Aptr-Encrypted: default header; the server decrypts it server-side.

type UploadResult

type UploadResult struct {
	ID           string `json:"id"`
	Filename     string `json:"filename"`
	SizeBytes    int64  `json:"size_bytes"`
	Destinations int    `json:"destinations"`
	LongPolling  bool   `json:"long_polling"`
}

UploadResult is the response from uploading an image.

type UploadRow

type UploadRow struct {
	ID                    string                       `json:"id"`
	Filename              string                       `json:"filename"`
	SizeBytes             int64                        `json:"sizeBytes"`
	MimeType              string                       `json:"mimeType"`
	Source                string                       `json:"source"`
	IsEncrypted           bool                         `json:"isEncrypted"`
	Env                   string                       `json:"env"`
	CreatedAt             string                       `json:"createdAt"`
	SessionID             string                       `json:"sessionId"`
	ProjectID             string                       `json:"projectId"`
	ProjectName           string                       `json:"projectName"`
	DestinationsTotal     int                          `json:"destinationsTotal"`
	DestinationsDelivered int                          `json:"destinationsDelivered"`
	DestinationsFailed    int                          `json:"destinationsFailed"`
	DestinationsBreakdown []UploadDestinationBreakdown `json:"destinationsBreakdown"`
	Status                string                       `json:"status"`
}

UploadRow is a summary row for an uploaded image.

type UploadsListPage

type UploadsListPage struct {
	Data       []UploadRow `json:"data"`
	Total      int         `json:"total"`
	Page       int         `json:"page"`
	PageSize   int         `json:"pageSize"`
	TotalPages int         `json:"totalPages"`
}

UploadsListPage is a paginated response of upload rows.

type UploadsResource

type UploadsResource struct {
	// contains filtered or unexported fields
}

UploadsResource provides methods for listing uploaded images.

func (*UploadsResource) List

List returns a paginated list of uploaded images.

func (*UploadsResource) Recent

func (u *UploadsResource) Recent(ctx context.Context, params LimitParams) ([]UploadRow, error)

Recent returns the most recently uploaded images.

type ValidationError

type ValidationError struct {
	AperturError
}

ValidationError indicates a 400 Bad Request response due to invalid input.

func NewValidationError

func NewValidationError(message string) *ValidationError

NewValidationError creates a ValidationError with the given message.

type VerifyPasswordResult

type VerifyPasswordResult struct {
	Valid bool `json:"valid"`
}

VerifyPasswordResult is the response from verifying a session password.

type WebhookDeliveriesOptions

type WebhookDeliveriesOptions struct {
	Page  *int `json:"page,omitempty"`
	Limit *int `json:"limit,omitempty"`
}

WebhookDeliveriesOptions holds pagination options for listing deliveries.

type WebhookDeliveriesResult

type WebhookDeliveriesResult struct {
	Deliveries []WebhookDelivery `json:"deliveries"`
	Total      int               `json:"total"`
	Page       int               `json:"page"`
	Limit      int               `json:"limit"`
}

WebhookDeliveriesResult is a paginated list of webhook deliveries.

type WebhookDelivery

type WebhookDelivery struct {
	ID           string  `json:"id"`
	EventLogID   string  `json:"eventLogId"`
	Topic        string  `json:"topic"`
	Status       string  `json:"status"`
	Attempts     int     `json:"attempts"`
	ResponseCode *int    `json:"responseCode"`
	ResponseBody *string `json:"responseBody"`
	DurationMs   int     `json:"durationMs"`
	LastError    *string `json:"lastError"`
	NextRetryAt  *string `json:"nextRetryAt"`
	CreatedAt    string  `json:"createdAt"`
	UpdatedAt    string  `json:"updatedAt"`
}

WebhookDelivery represents a single webhook delivery attempt.

type WebhookRetryResult

type WebhookRetryResult struct {
	Message string `json:"message"`
}

WebhookRetryResult is the response from retrying a webhook delivery.

type WebhookTestResult

type WebhookTestResult struct {
	Message string `json:"message"`
}

WebhookTestResult is the response from testing a webhook endpoint.

type WebhooksResource

type WebhooksResource struct {
	// contains filtered or unexported fields
}

WebhooksResource provides CRUD operations on event webhooks.

func (*WebhooksResource) Create

func (w *WebhooksResource) Create(ctx context.Context, projectID string, config CreateEventWebhookConfig) (*EventWebhook, error)

Create registers a new event webhook for the project.

func (*WebhooksResource) Delete

func (w *WebhooksResource) Delete(ctx context.Context, projectID, webhookID string) error

Delete removes an event webhook from the project.

func (*WebhooksResource) Deliveries

func (w *WebhooksResource) Deliveries(ctx context.Context, projectID, webhookID string, opts WebhookDeliveriesOptions) (*WebhookDeliveriesResult, error)

Deliveries returns a paginated list of delivery attempts for the webhook.

func (*WebhooksResource) List

func (w *WebhooksResource) List(ctx context.Context, projectID string) ([]EventWebhook, error)

List returns all event webhooks for the given project.

func (*WebhooksResource) RetryDelivery

func (w *WebhooksResource) RetryDelivery(ctx context.Context, projectID, webhookID, deliveryID string) (*WebhookRetryResult, error)

RetryDelivery retries a failed webhook delivery.

func (*WebhooksResource) Test

func (w *WebhooksResource) Test(ctx context.Context, projectID, webhookID string) (*WebhookTestResult, error)

Test sends a test event to the webhook endpoint.

func (*WebhooksResource) Update

func (w *WebhooksResource) Update(ctx context.Context, projectID, webhookID string, config UpdateEventWebhookConfig) (*EventWebhook, error)

Update modifies an existing event webhook.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL