Freedam

API Endpoints

All v1 endpoints are mounted under https://your-freedam-instance.com/api/v1 and require an API bearer token. Every request is rate limited (60/minute per token) and audited.

For authentication and token scopes see API Authentication. For rate-limit headers and the back-off contract see Rate Limiting. For the cookieless image transformation URLs (/i/, /is/, /ip/) and other asset delivery URLs that live outside /api/v1, see Image Transformations.

Conventions

  • Base URL - https://your-freedam-instance.com/api/v1
  • Auth header - Authorization: Bearer <your-token>
  • JSON body - send Content-Type: application/json on POST/PUT, except file uploads, which use multipart/form-data.
  • Asset identifier - assets are addressed by their GAID (Global Asset ID), a stable public id such as IM-20260309-UDXZH8PP6VPW. Every field that names an asset takes GAIDs, and responses return them: asset_gaid, asset_gaids, cover_asset_gaid.
  • Numeric routes - {collection}, {webhook}, {batch} and {share} take numeric ids.
  • Errors - validation errors return 422 with a message and an errors object keyed by field. A missing ability returns 403 with required_abilities. See Authentication.

Pagination

List endpoints accept page and per_page. Two response shapes exist:

Endpoints Default per_page Shape
Assets, collections 24 (max 100) data, links, meta with current_page, last_page, per_page, total
Shares, operations 20 data, links, meta
Webhooks, webhook deliveries 20 Flat: data, current_page, last_page, per_page, total, next_page_url at the top level

Endpoint catalogue

User

Method Path Ability Description
GET /v1/user any Authenticated user: id, name, email.

Tokens

Self-service token management for the user who owns the token. See Authentication.

Method Path Description
GET /v1/tokens List your tokens with abilities, last_used_at, last_used_ip and expires_at.
POST /v1/tokens Create a token. The plain-text token is returned once.
DELETE /v1/tokens/{token} Revoke a token immediately.

POST /v1/tokens body:

Field Rules
name Required string.
abilities Required array of ability names. You can't grant abilities your own role doesn't allow.
description Optional string.
expires_at Optional date.

Assets

Method Path Ability Description
GET /v1/assets assets:read Search and list assets.
GET /v1/assets/{gaid} assets:read One asset with its technical, descriptive and AI fields.
PUT /v1/assets/{gaid} assets:write Update an asset. Fields you omit are left unchanged.
DELETE /v1/assets/{gaid} assets:delete Move an asset to the Trash.

Results only include assets the token's user is allowed to see.

Search parameters for GET /v1/assets

Parameter Description
q Full-text and semantic search, up to 500 characters.
sort_by created_at (default), updated_at, title, original_filename, size, or relevance (default when q is set).
sort_direction asc or desc (default).
asset_class_id Only assets of this asset class.
mime_type MIME type or part of one, such as image/jpeg or video.
ingestion_batch_id Only assets from this upload batch.
filters Advanced rules as a JSON string, see below.
page, per_page Pagination, per_page up to 100.

filters accepts a single rule or nested and/or groups:

{
    "type": "group",
    "operator": "and",
    "rules": [
        { "type": "filter", "field": "asset.file_category", "operator": "equals", "value": "Image" },
        { "type": "filter", "field": "asset.width", "operator": "greater_than", "value": 1920 },
        { "type": "filter", "field": "metadata.campaign", "operator": "contains", "value": "Spring" }
    ]
}
  • Operators: equals, not_equals, contains, not_contains, starts_with, ends_with, greater_than, greater_than_or_equal, less_than, less_than_or_equal, in, not_in, between ([min, max]), is_empty, is_not_empty, color_equals, color_near.
  • Common fields: asset.title, asset.original_filename, asset.mime_type, asset.file_category (Image, Video, Audio, Document), asset.extension, asset.width, asset.height, asset.file_size, asset.created_at, asset.updated_at, asset.capture_date, asset.creator, asset.copyright, asset.keywords, asset.ai_caption, asset.ai_tags, asset.ocr_text, asset.workflow_status, asset.collections (with in/not_in), and metadata.{key} for custom fields.

Invalid JSON or an invalid rule tree returns 422.

Body for PUT /v1/assets/{gaid}

Field Rules
title String, up to 255 characters.
description String up to 2,000 characters, or null.
keywords Array of strings, each up to 100 characters. Replaces the existing keywords.
ai_caption, ocr_text String up to 5,000 characters, or null.
ai_tags Array of strings.
metadata Object of custom field values keyed by the field's key, for example {"campaign": "Spring 2026", "product_line": "outdoor"}.
workflow_status The status to move the asset to, when its workflow allows that transition.
asset_class_id Move the asset to another asset class.
curl -X PUT https://your-freedam-instance.com/api/v1/assets/IM-20260309-UDXZH8PP6VPW \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Hero shot Q3", "keywords": ["outdoor", "summer"], "metadata": {"campaign": "Spring 2026"}}'

The response is the updated asset in data. Every successful update sends an asset.updated webhook.

Video Embeds

Generate iframe embed codes for video assets. Each call mints (or reuses) a long-lived public share dedicated to embedding so you can drop the returned iframe_html straight into a CMS, blog post, or third-party site. Embed shares are isolated from regular /v1/shares and cannot be reached through that endpoint.

Required abilities: shares:read for GET, shares:manage for POST and DELETE.

Method Path Ability Description
GET /v1/assets/{gaid}/embed shares:read Return the existing embed code, or 404 if none.
POST /v1/assets/{gaid}/embed shares:manage Generate or refresh an embed code.
DELETE /v1/assets/{gaid}/embed shares:manage Revoke the embed code.

Only assets with a video/* MIME type can be embedded; calling these endpoints on any other asset returns 422.

Request body for POST (all fields optional)

Field Type Default Notes
width integer 640 Player width in pixels for the non-responsive iframe (160–3840).
height integer 360 Player height in pixels (90–2160).
responsive boolean true If true, the response also includes a responsive_html snippet.
autoplay boolean false Browsers force muted when autoplay is on.
muted boolean false Start muted.
loop boolean false Restart playback on end.
controls boolean true Show the player chrome.
start integer 0 Start offset in seconds.
allowed_domains array of string null Restrict the iframe to these origins via CSP frame-ancestors.
force_new boolean false Revoke the existing embed share and mint a fresh one.

Response

{
    "data": {
        "token": "shr_…",
        "asset_gaid": "A_01HXYZ…",
        "embed_url": "https://your-freedam-instance.com/embed/shr_…/A_01HXYZ…?autoplay=1",
        "iframe_html": "<iframe src=\"…\" width=\"640\" height=\"360\" …></iframe>",
        "responsive_html": "<div style=\"position:relative;padding-bottom:56.25%…\">…</div>",
        "width": 640,
        "height": 360,
        "expires_at": "2027-05-06T12:00:00+00:00",
        "allowed_domains": null,
        "options": {
            "autoplay": false,
            "muted": false,
            "loop": false,
            "controls": true,
            "start": 0
        }
    }
}

A repeated POST for the same asset returns 200 with the existing share (and refreshes its expiry when it is within 30 days of expiring); a fresh share returns 201.

Collections

Method Path Ability Description
GET /v1/collections collections:read List collections you can view.
GET /v1/collections/{collection} collections:read One collection.
POST /v1/collections collections:write Create a collection.
PUT /v1/collections/{collection} collections:write Update a collection.
DELETE /v1/collections/{collection} collections:delete Delete a collection.
POST /v1/collections/{collection}/assets collections:write Add assets.
DELETE /v1/collections/{collection}/assets collections:write Remove assets.
  • List filters: collection_type_id, parent_id (children of that collection), root_only=1 (top-level collections only), is_active, per_page.
  • Create body: name (required), collection_type_id (required), description, parent_id, is_active, is_public, cover_asset_gaid (an asset you can view).
  • Update body: any of name, description, parent_id, is_active, is_public, cover_asset_gaid. Send "cover_asset_gaid": null to remove the cover.
  • Add assets: POST a JSON body {"asset_gaids": ["IM-…", "VI-…"]}.
  • Remove assets: DELETE with the GAIDs in the query string: ?asset_gaids[]=IM-…&asset_gaids[]=VI-….

Adding and removing report partial results: the response contains a message such as "2 asset(s) added to collection.", the number of assets that succeeded, and failed and errors entries describing the assets that could not be added or removed. Check them rather than assuming every GAID was processed.

Uploads

Ability: uploads:manage. Uploading is a three-step flow.

Method Path Description
POST /v1/uploads/batches Create an upload batch.
POST /v1/uploads/batches/{batch}/files Upload one file into the batch.
GET /v1/uploads/batches/{batch} Read the batch status and per-file progress.
  1. Create a batch. All fields are optional defaults for the files in the batch: batch_name, asset_class_id, collection_id, target_workflow_status, title, description, keywords (array), creator, copyright, location, metadata (object keyed by field key). The response contains the batch id and batch_uuid.
  2. Upload each file as multipart/form-data, one file per request, with the binary in file. You can override the batch defaults per file with title, description, creator, copyright, location, asset_class_id and collection_id. Because multipart forms can't nest values, send keywords as a JSON array string (["landscape","sunset"]) and metadata as a JSON object string.
  3. Poll the batch until it has finished. Each file moves through uploading, scanning, storing, processing_metadata, processing_ai, finalizing and completed, or ends in failed. The batch reports total_files, processed_files, successful_files, failed_files and is_completed.
curl -X POST https://your-freedam-instance.com/api/v1/uploads/batches/42/files \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "[email protected]" \
  -F "title=Hero shot Q3" \
  -F 'keywords=["outdoor","summer"]'

Instead of polling, subscribe to the upload.batch_completed and upload.batch_failed webhooks. To find the assets a batch created, list assets with ingestion_batch_id.

Metadata

Ability: metadata:read. A read-only catalogue of field definitions, vocabularies and terms, to build your own forms without hard-coding workspace-specific values.

Method Path Description
GET /v1/metadata/definitions Field definitions. Filter with asset_class_id.
GET /v1/metadata/vocabularies Vocabularies with id, name, code, is_tree.
GET /v1/metadata/vocabularies/{vocabulary} One vocabulary with its terms.
GET /v1/metadata/vocabularies/{vocabulary}/terms Terms of a vocabulary. For tree vocabularies, pass parent_id to list children.
GET /v1/metadata/vocabularies/{vocabulary}/terms/{term} One term.

Use the definition key as the property name in metadata objects when updating assets or uploading.

Shares

Method Path Ability Description
GET /v1/shares shares:read Shares created by the token's user. Filter with shareable_type.
GET /v1/shares/{share} shares:read One share.
POST /v1/shares shares:manage Create a share link.
PUT /v1/shares/{share} shares:manage Update access, permissions, dates or is_active.
DELETE /v1/shares/{share} shares:manage Delete a share.
POST /v1/shares/{share}/revoke shares:manage Stop a share immediately.

POST /v1/shares body:

Field Rules
shareable_type Required: collection, asset or selection.
shareable_id For collection: the collection's numeric id.
asset_gaid For asset: the asset's GAID.
asset_gaids For selection: an array of asset GAIDs.
access_type Required: public, email_restricted, password_protected or private.
allowed_emails, allowed_domains Arrays. At least one of them is required for email_restricted.
password At least 6 characters, for password_protected.
permissions {"view": true, "download": false}
download_resolution original, w_5120, w_4096, w_2048, w_1024, w_512, w_256 or w_128.
watermark_id A watermark id, when your plan includes watermarks.
starts_at, expires_at Dates; expires_at must be after starts_at.
acknowledge_rights_warnings true to create the share even when rights policies block some assets.

A share created through the API behaves exactly like one created in Freedam:

  • You need the right to share what you send: assets.share and access to (and download of) every asset, or for a collection, collections.share on a collection you created. An unknown GAID is refused with the same 403 as an asset you may not share.
  • Rights policies are checked: a public share needs the publish action on every asset, other access types distribute. A blocked share returns 403 with "error": "rights_blocked" and the blocked_assets (with their asset_gaid). Resend with acknowledge_rights_warnings: true to create it anyway; blocked assets stay hidden from recipients.
  • If your workspace requires accepting share terms of use, the request returns 409 with "error": "consent_required" until the token's user has accepted them in Freedam.
  • Each address in allowed_emails receives an invitation email, and the share.created webhook is sent. Adding addresses with PUT invites the new ones and tells existing recipients what changed.

Share responses identify what is shared with shareable_type plus shareable_id (collections), asset_gaid (a single asset) or asset_gaids (a selection). See Share Links for how each option behaves for recipients.

Operations

Long-running asynchronous operations. POST /v1/operations requires an Idempotency-Key header - replaying the same key returns the original operation instead of creating a new one. The body is {"type": "...", "params": {...}}. Any other type is rejected with 422.

type What it does params Ability
asset_upload_batch Creates an upload batch to send files into. Optional: batch_name, asset_class_id (integer), collection_id, target_workflow_status uploads:manage
asset_bulk_update Applies the same metadata updates to many assets. Required: asset_gaids (array of GAIDs), updates (object) assets:write
Method Path Description
GET /v1/operations Your operations. Filter with type and status.
POST /v1/operations Start an operation.
GET /v1/operations/{operation} Status, progress_percentage, current_stage, result and error.
POST /v1/operations/{operation}/cancel Cancel a pending or processing operation.

Operation status is one of pending, processing, completed, partially_completed, failed or cancelled.

asset_bulk_update only changes the assets the token's user can view and edit. The operation's result lists every other GAID in errors as {"asset_gaid": "…", "error": "Asset not found or not updatable."}, whether the asset does not exist or you may not edit it; the operation then ends as partially_completed or failed.

Webhooks

No ability is needed: each token manages the webhook endpoints of its own user. See Webhooks for bodies, events and signatures.

Method Path
GET /v1/webhooks
POST /v1/webhooks
GET /v1/webhooks/{webhook}
PUT /v1/webhooks/{webhook}
DELETE /v1/webhooks/{webhook}
POST /v1/webhooks/{webhook}/test
GET /v1/webhooks/{webhook}/deliveries
POST /v1/webhooks/{webhook}/rotate-secret

Consents

Compliance and audit endpoints. Ability: consents:read.

Method Path Description
GET /v1/consents/me Terms of use you have accepted and those still pending.
GET /v1/consents/users/{user} The same for another user, by numeric id.
GET /v1/consents/users/{user}/history The append-only acceptance history for a user, paginated.

OpenAPI specification

A machine-readable OpenAPI 3.1 spec for every endpoint above is available at /docs/api.json. It is the source of truth used to generate the official SDKs. Generate a client in any language with openapi-generator or Kiota.

show.relatedDocs.heading

show.relatedDocs.subheading