DAM Wiki

Phraseanet API

Alchemy · Paris, France · Founded 1996 · independent (privately held French SARL)Verified 2026-10-29 · 79 sources
  • SaaS
  • On-premise
  • SMB to enterprise (companies, public sector, photographers)
  • REST API
  • OpenAPI spec
  • Webhooks
  • SAML · OIDC SSO
Complete · 7 of 7 pages
79sources
3API specs
10-29verified 2026
Official website ↗Phraseanet alternatives →

In brief

From this page’s summary fields, verified 2026-10-29. Sources in each section.
Authentication (details in section Authentication)
OAuth 2.0 (authorization code, PKCE, client credentials, password), API key
Rate limit (details in section Limits & quirks)
Phraseanet v1: none; Phrasea SaaS plans: 5-40 concurrent requests + request quotas
Webhooks (details in section Events & webhooks)
Phrasea: admin-managed entity events, unsigned; Phraseanet: per OAuth app, 17 events
Pagination (details in section At a glance)
Phrasea: page + limit (max 100); Phraseanet v3: offset/limit or page/per_page (max 100)
API spec (details in section Stored API specs)
OpenAPI 3.1.0 Databox (239 ops) + Expose (37 ops); Phraseanet v3 OpenAPI 3.0.3 (7 ops)

Scope: two API families from the same vendor.

  • Phrasea (current): one REST API per service (Databox, Expose, Uploader), built with Symfony and API Platform. Authentication goes through Keycloak.
  • Phraseanet 4.1 (legacy): one PHP application exposing API v1, v2 and v3 under /api/, with its own OAuth2 server.

Every installation is a separate server; there is no shared multi-tenant API host. {domain} stands for the base domain of a Phrasea installation and {host} for a Phraseanet server. No authenticated call was made for this page. The OpenAPI documents of the vendor's public demo instance were read without credentials.

At a glance

API styles
REST (JSON / JSON-LD; Phraseanet v1 also YAML and JSONP) S35 S43
Base URL(s)
Phrasea: https://api-databox.{domain}/, https://api-expose.{domain}/, https://api-uploader.{domain}/ (default {domain} is phrasea.local); Keycloak at https://keycloak.{domain}/realms/phrasea S34. Phraseanet: https://{host}/api/v1/, /api/v2/, /api/v3/; OAuth2 at /api/oauthv2/; report API at /api/report S52
Current version(s) & deprecations
Phrasea: the APIs report version "1.0.0" S39 S40; the product follows release numbers (4.5.2 on 2026-10-21) S23. Phraseanet: the docs call API 1.5.0 and 2.0.0 stable on Phraseanet 4.0+ S42; v3 is documented on SwaggerHub S47. records/search has been deprecated since API 1.3 S48. Vendor-side, Phrasea replaces Phraseanet in 2026; no end-of-support date for the Phraseanet API is published S1 S3
Auth methods
Phrasea: OAuth2 / OpenID Connect bearer tokens issued by Keycloak. The specs declare the authorization-code flow S39. The demo realm also advertises client credentials, password, refresh token, device code and token exchange, with PKCE S256 S67. Service accounts are documented S28. The Uploader→Databox target uses an ApiKey scheme S30. A one-time-token endpoint (POST/ott) exists S39. Phraseanet: OAuth2 authorization_code and password grants S44
Token lifetime / refresh
Phrasea: set in the Keycloak realm; the default value Alchemy ships is Not public S28. Phraseanet: "OAuth access tokens do not expire"; users revoke them from their account settings S44
Scopes / permission model
Phrasea: Keycloak scopes per service, <resource>:<action> (e.g. asset:read, collection:edit, basket:list, integration:owner), plus OIDC scopes. Keycloak roles admin / <service>-admin. Object-level ACLs on workspaces, collections and assets S28 S29 S22. Phraseanet: no OAuth scopes documented; calls run with the rights of the user who authorised the app S44
Official spec
Phrasea: OpenAPI 3.1.0 generated at runtime by API Platform (/docs.json). Databox: 143 paths / 239 operations; Expose: 20 paths / 37 operations, read on the vendor demo S39 S40. Uploader: login required S66. Phraseanet: API v3 OpenAPI 3.0.3 (7 operations) on SwaggerHub and in the repository S49 S50; v1/v2 are documented as HTML pages only S42. Archived copies on DAM Wiki: API spec downloads
Rate limits
Phraseanet v1: none S43. Phrasea self-hosted: none documented (Unknown). Alchemy SaaS plans: 5 / 20 / 40 concurrent requests and "500k PUT, 1M GET" / "1M PUT, 2M GET" / "2M PUT, 4M GET" HTTP/API requests (period not stated) S15
Pagination
Phrasea: page (from 1) + limit; at most 100 items per page in Databox S35 S39. Phraseanet v3: offset/limit or page/per_page, max 100, default 10 S50. Phraseanet v1: offset_start on search (renamed from page in API 1.2) S48
Webhooks / events
Phrasea: webhooks managed in the admin back office; events `{entity}:create
Official SDKs
Phraseanet PHP SDK (phraseanet/php-sdk, last version 7.0.1 on 2021-02-24) S62 S76. No official Phrasea SDK; the Phrasea front ends use internal @alchemy/* TypeScript packages from the monorepo S22
Sandbox / trial access
Self-host from source (Docker Compose) S22 S19. The vendor demo instance needs an account S11

Authentication

Phrasea (Keycloak) S28 S39 S67

  1. Each Phrasea installation runs a Keycloak realm (default name phrasea) S34. OIDC discovery lives at https://keycloak.{domain}/realms/phrasea/.well-known/openid-configuration S67.
  2. Interactive apps use the authorization-code flow (/protocol/openid-connect/auth → /protocol/openid-connect/token), which the Databox and Expose specs declare as their oauth security scheme S39 S40.
  3. Machine-to-machine: Keycloak clients with service accounts (service_account scope) and the client-credentials grant S28 S67. Admins create clients and assign roles and scopes in the Keycloak admin console S28.
  4. Send Authorization: Bearer {access_token} to api-databox.{domain} etc. S39.
  5. Admin rights: Keycloak role admin (all services) or <service>-admin (one service); Super Admin can do everything S29.

Phraseanet 4.1 (built-in OAuth2) S44 S51

  1. A user registers an application (name, callback URL) from the account settings, reached by clicking their login in the menu bar. Phraseanet returns a client ID and secret S44.
  2. Authorization: GEThttps://{host}/api/oauthv2/authorize with response type code, token or code_and_token S44.
  3. Token: POSThttps://{host}/api/oauthv2/token with grant_type=authorization_code. The password grant is allowed for highly trusted clients S44.
  4. Pass the token as the oauth_token query parameter or in the Authorization header. HTTPS is required S44 S43.
  5. Phraseanet can also delegate login to an OpenID Connect provider such as a Phrasea Keycloak (openid and ps-auth providers) S56 S57.

Core resources

Phrasea — Databox API (https://api-databox.{domain}), from the vendor demo OpenAPI S39 and the next branch source S79.

ResourceEndpointsNotes
AssetsGET/POST /assets, GET/PUT/PATCH/DELETE /assets/{id}, POST/assets/multiple, /assets/move, /assets/copy, /assets/add-to-collection, /assets/delete-multiple, /assets/restore-multiple, GET/assets/suggest, GET/assets/geo-clusters, POST/assets/{id}/add-as-version, PUT/assets/{id}/trigger-workflow, POST/assets/{id}/attributes, GET/assets/{id}/duplicates, GET/assets/{id}/metrics29 operations on the demo. Soft delete and restore. GET/assets/{id}/similar (kNN) is in the source but not on the demo S79 S30
Metadata valuesGET/POST /attributes, GET/PUT/PATCH/DELETE /attributes/{id}, POST/attributes/batch-updateOne attribute = one value of a definition on an asset
Metadata schema/attribute-definitions (CRUD, /sort, /{id}/duplicate), /field-types, /built-in-attributes, /locales, /attribute-policies, /attribute-filter-rulesPer-workspace definitions
Controlled vocabularies/entity-lists (CRUD, /{id}/import, /{id}/export, /{id}/clear), /attribute-entities (CRUD, PUT/{id}/merge)Pending / approved values (4.0+) S23
Tags/tags (CRUD)Tags drive access rules S8
WorkspacesGET/POST /workspaces, GET/PUT/DELETE /workspaces/{id}, /workspaces/{id}/flush, /logo, /terms, /terms/sign, GET/workspaces-by-slug/{slug}Top-level container
Collections/collections (CRUD), /collections/{id}/ascendants, PUT/collections/{id}/move/{dest}, /follow, /unfollow, /delete-multiple, /restore-multiple, /collection-assetsNested hierarchy
SearchGET/assets?query=…&conditions[]=… (AQL), GET/assets/suggest, /saved-searches (CRUD)See Search & querying
UploadsGET/POST /uploads, GET/DELETE /uploads/{id}, POST/uploads/{id}/partMultipart upload to S3 S38
Files & versionsGET/files/{id}, /files/{id}/metadata, /files/{id}/duplicates, /asset-file-versionsTechnical metadata per file
Renditions/renditions (CRUD), /rendition-definitions (CRUD, /sort, /{id}/duplicate), /rendition-policies, GET/rendition-build-referenceDefinitions per workspace
Attachments/attachments (CRUD)Files attached to an asset
Sharing/shares (CRUD), GET/shares/{id}/public, GET/s/{id}/r/{rendition}, GET/s/{id}/a/{attachment}Public, time-limited share links
Baskets/baskets (CRUD), /baskets/{id}/assets, /baskets/default/assets, /archive, /unarchive, /removeSelections, publishable to Expose
Rights/asset-policies, /attribute-policies, /rendition-policies, /attribute-filter-rulesUsers and groups come from Keycloak, not the Databox API S28
WorkflowsGET/workflows, GET/workflows/{id}, POST/workflows/{id}/cancel, POST/workflows/{id}/jobs/{jobId}/rerunWorkflow state per run
Integrations/integrations (CRUD), /integration-types, /integration-datas, /integration-tokensAI and third-party connectors per workspace S30
Templates & exports/asset-data-templates, /template-attributes, POST/asset-exportsImport templates, export jobs
Collaboration/messages, GET/threads/{threadId}/messagesDiscussions on assets
Other/pages, /page-by-slug/{slug}, /profiles, /operation-tasks, POST/ottPages, display profiles, admin tasks, one-time tokens

Phrasea — Expose API (https://api-expose.{domain}) S40: /publications (CRUD, /slug-availability/{slug}, /{id}/assets, /{id}/sort-assets), GET/publications/{publicationSlug}/assets/{assetSlug}, /assets (CRUD, /{id}/sub-definitions), /sub-definitions, /publication-profiles, /download-requests, /uploads.

Phrasea — Uploader API (https://api-uploader.{domain}): resources Asset, Commit, FormSchema, Target, TargetParams, MultipartUpload S66. Key routes: POST/commit, POST/commits/{id}/ack, POST/assets/{id}/ack, GET/targets/{id}/form-schema S79 S32.

Phraseanet 4.1 (paths relative to https://{host}/api/v1, /v2, /v3) S51 S46 S50

ResourceEndpointsNotes
Userv1 GET/me/, /me/collections/, /me/structures/, /me/subdefs/, POST/me/update-account/, /me/update-password/, /me/request-collections/
Databases & collectionsv1 GET/databoxes/list/, /databoxes/{databox_id}/collections/, /status/, /metadatas/, /termsOfUse/, GET/collections/{base_id}/; v3 GET/databoxes/{databox_id}/subdefs/Metadata structure per database
Records (assets)v1 GET/records/{databox_id}/{record_id}/ (+ /caption/, /metadatas/, /status/, /embed/, /related/), POST/records/add/, POST…/setmetadatas/, …/setstatus/, DELETE/records/{databox_id}/{record_id}/; v3 GET/PATCH /records/{databox_id}/{record_id}/, POST/records/{base_id}/v3 PATCH sets metadata and status bits
Storiesv1 GET/stories/{databox_id}/{record_id}/ (+ /embed/), POST/stories, /addrecords, /delrecords, /setcover; v3 GET/stories/{databox_id}/{record_id}/children/
Searchv1 /search/; v2 /search/; v3 POST/search/, POST/searchraw/records/search deprecated
Quarantinev1 GET/quarantine/list/, /quarantine/item/{id}/; v2 POST/quarantine/item/{id}/add/, DELETE/quarantine/item/{id}/
Basketsv1 /baskets/list/, /baskets/add/, /baskets/{basket}/content/, /setname/, /setdescription/, /delete/; v2 POST/DELETE /baskets/{basket}/records/, PUT…/records/reorder
Ordersv2 GET/POST /orders/, GET/orders/{id}, POST/orders/{id}/accept, /deny, GET/orders/{id}/archive
Feedsv1 /feeds/list/, /feeds/{feed_id}/content/, /feeds/content/, /feeds/entry/{entry_id}/Publications
Renditionsv1 /records/…/embed/, POST/embed/substitute/, /me/subdefs/"Sub-definitions"
Accountsv1 POST/accounts/access-demand/, /accounts/reset-password/{email}/, …
Uploadsv1 POST/records/add/, POST/upload/enqueue/Enqueue used by the Phrasea Uploader S32
Monitoringv1 /monitor/phraseanet/, /monitor/scheduler/, /monitor/tasks/, POST/monitor/task/{task}/start/, /stop/; v3 /monitor/data/Admin

Data model

Phrasea S22 S39 S30

  • Workspace → Collections (nested; an asset can sit in several) → Assets. Assets can be stories that contain other assets.
  • Asset: owner, privacy level, tags, attributes (values of attribute definitions, multilingual, possibly multi-valued, possibly entities from an entity list), renditions (built from rendition definitions), a source File with versions, attachments, annotations and discussion threads.
  • Integrations and workflows are attached to a workspace. Webhooks are global to a service S36.
  • Identifiers: string IDs in the API (UUID-style; the spec types them only as strings) S39. Users and groups are Keycloak identities S28.

Phraseanet 4.1 S50 S46

  • Databox (sbas_id / databox_id: a metadata database with its own structure) → Collections (base_id) → Records (record_id, unique within a databox).
  • A record has a caption (metadata fields), status bits, sub-definitions (renditions such as thumbnail, preview and document) with permalinks, and can be a story.
  • A record is identified by the pair {databox_id}/{record_id}.

Search & querying

Phrasea S31 S39 S35

  • GET/assets with query (full text), conditions[] (AQL), workspaces[], parents[], collection, story, ids[], include_deleted, page.
  • AQL examples: title STARTS WITH "Report" AND (@tag HAS ALL OF ("a","b") OR description IS EMPTY); location WITHIN CIRCLE (48.85, 2.35, "1500m"); dates with prefix matching (@createdAt IS "2024-03"). CONTAINS / STARTS WITH / ENDS WITH are case-insensitive unless CASE SENSITIVE is added. They work on the raw value, which is indexed up to 256 characters S31.
  • Facets, sorting, suggestions (/assets/suggest), geo clusters (/assets/geo-clusters) and kNN similarity on CLIP embeddings S22 S30.
  • Page size: limit, max 100 S35. The maximum depth of deep pagination is not documented (Unknown).

Phraseanet S50

  • v3 POST/search/: query (full text with operators, e.g. dogs OR cats; empty = all), search_type (0 records, 1 stories), bases[] (collection IDs), paging with offset/limit or page/per_page (1–100, default 10), story_children_limit, include[] to add facets or story children (left out by default).
  • v3 POST/searchraw/ returns raw search-engine results S50 S51.

Uploads & binaries

Phrasea

  • Multipart upload S38 S39: POST/uploads starts the upload, POST/uploads/{id}/part returns the URL for the next part, the client PUTs the part to object storage, then the upload is completed and attached to an asset. DELETE/uploads/{id} cancels it. The source also has POST/uploads/{id}/parts (batch of part URLs) S38.
  • Signed URLs: request signatures expire after 3,600 s for Databox and Expose and 600 s for Uploader by default (*_REQUEST_SIGNATURE_TTL). Optional CloudFront signed delivery (TTL 86,400 s) S34.
  • Uploader commits: users upload files, then commit the batch. The target (Databox, Phraseanet or another endpoint) is notified (push) or polls GET/commits (pull). It downloads each asset with GET/assets/{id}/download and acknowledges with POST/commits/{id}/ack S32.
  • Assets can also be created from a URL S22.

Phraseanet

  • POST/api/v1/records/add/ (multipart file + base_id; nosubdefs skips rendition generation). Files may land in quarantine S48 S46.
  • POST/api/v3/records/{base_id}/ creates a record S50.
  • Downloads: sub-definition permalinks (/permalink/v1/{databox_id}/{record_id}/{subdef}/…?token=…) with url, page_url and download_url S50 S48.

Events & webhooks

Phrasea S36 S37 S30

  • Entity webhooks: admins manage them in the service's admin back office (EasyAdmin CRUD). Each webhook has a URL, a list of events, an active flag, "verify SSL", a timeout (default 30 s) and a secret field.
  • Events (Databox): {entity}:create, {entity}:update, {entity}:delete for asset, attribute, attribute_definition, collection, rendition, rendition_definition, rendition_policy, tag, workspace S37.
  • Delivery: HTTP POST with JSON body {"event": …, "payload": …}; redirects are not followed. Failed deliveries are stored in a webhook log S36.
  • Signature: Unverified none found. The secret field exists but the delivery code reviewed on 2026-10-29 does not send it or sign the body. Retries: none found in the delivery handler (Unknown).
  • Workflow webhook (core.webhook integration): calls a configurable URL (method, options, optional inputs and origin) as a workflow step S30. Saved-search automations can also fire webhooks S79.
  • Real time: WebSocket notifications to clients through Sockudo S22.

Phraseanet 4.1 S45 S53 S54 S55

  • Configured per OAuth application: webhook URL, active flag, list of listened events (empty = all) S55 S54.
  • Events in the code: record.created, record.edited, record.deleted, record.media_substituted, record.collection_changed, record.status_changed, record.subdef.created, record.subdef.creation_failed, record.subdefs.created, order.created, order.delivered, order.denied, user.created, user.deleted, user.registration.granted, user.registration.rejected, new_feed_entry S53. Unverified The public docs still say only new_feed_entry exists S45.
  • Delivery: JSON POST with a Phraseanet/{version} User-Agent and a default timeout of 30 s. Events are only sent when the app creator has rights on the affected collection or record. Failed deliveries go to a retry queue up to a configured maximum, then are logged S54.
  • Signature: the application model has an hmac_key column S55, but the webhook worker does not use it Unverified (inference from code); the docs say nothing about signing S45.

Limits & quirks

  • Phrasea API doc on the demo vs the code: the demo instance's OpenAPI lacks some routes in the current source (/assets/{id}/similar, /saved-search-automations) S39 S79. Unverified The demo probably runs an earlier release; its version is not exposed.
  • API Platform conventions: JSON-LD (application/ld+json) or plain JSON. PATCH takes application/merge-patch+json S35.
  • Production readiness: Alchemy says its Docker Compose and Helm containers are "primarily designed for development and testing" and need hardening for production. It recommends managed PostgreSQL and S3 S27.
  • Phraseanet v1 envelope: every response wraps meta (api_version, http_code, error_type, error_message…) and response. With JSONP the HTTP status is 200 and the real code sits in meta.http_code S43.
  • Phraseanet v1 has no anonymous access; every call needs a token S43.
  • Phraseanet v3 spec coverage: the spec documents 7 operations, while the v3 routes also include /monitor/data/, /databoxes/subdefs/ and a sub-definition service callback S50 S51.
  • Breaking change history (Phraseanet): API 1.2 renamed fields and changed collection shapes; later versions were backward-compatible S48.
  • Legacy runtime: Phraseanet 4.1 requires PHP 7.0 S59, which has been end-of-life since 2019-01-10 S69.

SDKs, tools & code samples

LibraryLanguageRepo / packageStatus
Phraseanet PHP SDKPHPalchemy-fr/Phraseanet-PHP-SDK, Packagist phraseanet/php-sdkOfficial; 7.0.1 on 2021-02-24; repository last pushed 2024-07-11 S62 S76
Phraseanet PHP SDK Silex providerPHPalchemy-fr/Phraseanet-PHP-SDK-Silex-ProviderLast push 2013 S64
Phraseanet-Clientsvariousalchemy-fr/Phraseanet-ClientsLast push 2012 S64
Phrasea @alchemy/* TypeScript packagesTypeScriptmonorepo lib/jsInternal packages of the Phrasea front ends (API client, auth, multipart upload) S22; publication on npm not verified (Unknown)
Media librariesPHPPHPExiftool, Zippy, BinaryDriver, PHP-Unoconv, PHP-FFMpeg fork…Building blocks of Phraseanet; Zippy 476 stars S64
Postman collection——None found (Unknown)

Changelog of the API

DateChange
2026-10-01Phrasea 4.5.0: workspace terms & conditions, multi-asset sharing, multipart upload for logos and terms PDFs S23
2026-06-30Phrasea 4.0.0: capability payloads change from canX booleans to an object (edit, delete, share, editPermissions, createAsset…); pending attribute entities; rendition rules and collection-level tag filter rules deprecated S23
2025-05-15Phraseanet API v3 spec: stories referenced in search results (include[]=results.records.stories) S50
2023-12-06Phrasea 3.0.0: authentication moves from the in-house Auth service to Keycloak (Symfony 6, API Platform 3) S23
2023-05-11Phrasea 2.0.0: workflows; Expose breaking changes S23
2020-06-30Phraseanet API v3 published on SwaggerHub S49
UndatedPhraseanet API 2.0.0: search v2, orders, single-record deletion. API 1.5.0 (Phraseanet 3.8.8): embed/substitute, nosubdefs. 1.4.0 (3.8.4): me route. 1.3 (3.7.5): stories; records/search deprecated. 1.2: breaking renames (offset_start, updated_on…) S48

Stored API specs

3 files · 821 KB · verbatim copies of public vendor filesSpecs README & provenance
FileFormatSizeDownload
phrasea_databox_api_openapi.jsonOpenAPI567 KBDownload
phrasea_expose_api_openapi.jsonOpenAPI106 KBDownload
phraseanet_api_v3_openapi.yamlOpenAPI149 KBDownload
Search the wiki