DAM Wiki

Pimcore (Digital Asset Management) API

Pimcore GmbH · Salzburg, Austria · Founded 2013 · independentVerified 2026-10-29 · 96 sources
  • On-premise
  • Private cloud
  • PaaS
  • Mid-market, enterprise
  • REST + GraphQL + webdav API
  • Partial OpenAPI
  • Webhooks
  • OIDC SSO
  • MCP: self-hosted
Complete · 7 of 7 pages
96sources
0API specs
10-29verified 2026
Official website ↗Pimcore alternatives →

In brief

From this page’s summary fields, verified 2026-10-29. Sources in each section.
Authentication (details in section Authentication)
API key, Session login, OAuth 2.0 (PKCE), Personal token
Rate limit (details in section Limits & quirks)
Studio API 500 req/min per IP, MCP 3,000/min (defaults, configurable); Datahub: none documented
Webhooks (details in section Events & webhooks)
Datahub Webhooks (Enterprise): UI-configured, custom headers, no signature, one attempt
Pagination (details in section At a glance)
GraphQL first/after offset; Studio page/pageSize; Simple REST page_cursor (search_after)
API spec (details in section At a glance)
OpenAPI 3.1 for Studio API on GitHub (POCL, not archived); GraphQL schema per endpoint

Scope: the APIs that expose Pimcore assets, Platform Version 2026.3. Pimcore is self-hosted or runs on Pimcore PaaS. Every installation is its own server with no shared multi-tenant host, so {host} below is the customer's Pimcore domain. Several surfaces exist side by side, each with its own authentication. No authenticated call was made for this page.

SurfaceStyleEditionIntended for
Datahub GraphQLGraphQL, one endpoint per configurationCore (all editions)Integrations and front ends S2 S62
Datahub Simple RESTREST, read-only, served from the search indexEnterpriseFast catalogue and asset delivery S2 S69
Studio Backend APIREST/JSON, OpenAPI 3.1CoreThe API behind the Pimcore Studio UI S59
WebDAVWebDAVCoreMounting the asset tree S31
Datahub WebhooksOutbound HTTPEnterpriseEvent push to other systems S73
MCP endpointsMCP (streamable HTTP)Experimental; Simple REST MCP needs EnterpriseAI agents S72 S55
PHP APIIn-process PHPCoreCustom bundles, importers, commands S32

At a glance

API styles
GraphQL (Datahub) S62; REST (Studio Backend API, Datahub Simple REST) S59 S69; WebDAV S31; MCP S56. No SOAP. CMIS is not native; the vendor says it needs a connector S1
Base URL(s)
GraphQL: https://{host}/pimcore-graphql-webservices/{configName} (route can be overridden) S62. Simple REST: https://{host}/pimcore-datahub-webservices/simplerest/…, Swagger UI at /pimcore-datahub-webservices/simplerest/swagger S70. Studio API: https://{host}/pimcore-studio/api/… S60. WebDAV: https://{host}/asset/webdav S31. MCP: https://{host}/pimcore-mcp/… and https://{host}/pimcore-datahub-webservices/simplerest-mcp S56 S72. OAuth: https://{host}/pimcore-oauth/authorize, /pimcore-oauth/token S57
Current version(s) & deprecations
APIs follow Platform Versions: one major per year (e.g. 2026.1) and minors about quarterly (2026.3 is current). Breaking changes only at yearly majors, under a Symfony-style backward-compatibility promise S7 S89. No version segment in API paths S60. Deprecations: legacy tree-based Datahub adapter schemas become read-only, with removal in 2027.1 S9; legacy portal frontend removed in 2027.1 S11; legacy /admin/* controllers removed in 2026.1 S9
Auth methods
GraphQL and Simple REST: API key per endpoint configuration S63 S70. Simple REST also accepts OAuth access tokens S70. Studio API: session login (username/password with optional 2FA, or user token) S60. MCP: static personal access tokens, OAuth tokens, per-chat pmcp_ tokens or the Studio session S56. Embedded OAuth 2.1 server (experimental, off by default): authorization code + PKCE S256 only, no client-credentials grant S57. WebDAV: Pimcore user credentials S31
Token lifetime / refresh
OAuth 2.1 defaults: access token 3,600 s, refresh token 2,592,000 s (30 days), authorization code 600 s, all configurable S57. Datahub API keys never expire; they are generated and rotated in the configuration S63. Studio session lifetime: Not public
Scopes / permission model
Requests act as a Pimcore user (Studio, MCP, OAuth) or as a Datahub configuration (API key). Datahub configs have workspaces with create/read/update/delete per folder, plus an optional "skip permission check" switch S63. OAuth scopes mcp:read/mcp:write are "consent labels" only; the user's own permissions decide S56. Tokens are bound to one resource (audience) S57
Official spec
Studio Backend API: OpenAPI 3.1.0 generated with swagger-php. Served at /pimcore-studio/api/docs/json (Swagger UI at /pimcore-studio/api/docs in dev) S59. A copy (info.version 2026.2, 683 paths, 815 operations) is committed to the public studio-ui-bundle repository S60. Simple REST: Swagger UI per instance S69. GraphQL: schema generated per endpoint, with introspection on by default S63. Not archived on DAM Wiki (POCL licence); see API spec downloads
Rate limits
Studio API: 500 requests/min per client IP (sliding window); MCP: 3,000/min; failed MCP logins: 5 per 5 min; password reset 5 per 5 min. Enabled by default, configurable or switchable off. X-RateLimit-* headers; HTTP 429 when exceeded S58. Datahub GraphQL/REST: none documented S62 S69
Pagination
GraphQL listings: first (limit) and after (offset), totalCount S64 S66. Studio API: page and pageSize query parameters S60. Simple REST: opaque page_cursor (also in the Link header). It switches to search_after beyond max_results_window (10,000 default), so deep paging works; MCP page size 1–200, default 25 S71 S72
Webhooks / events
Datahub Webhooks (Enterprise): add, update, delete and failure events for assets, documents and objects, plus workflow entered/completed. Configured in Studio, JSON payload, optional base64 binary, custom headers. No signature; one delivery attempt S73 S74 S76 S77
Official SDKs
None for remote clients (no JS/Python/PHP client library for the HTTP APIs found) S90. In-process PHP API S32. Studio UI SDK (React, RTK Query generated from the OpenAPI file) for UI plugins S60
Sandbox / trial access
Free Community Edition to self-install (product registration key required) S88; public demo listed by the vendor S87. Enterprise APIs (Simple REST, Webhooks) need an Enterprise licence or a Developer Licence Agreement for demos S2 S4

Authentication

Datahub GraphQL (API key) S62 S63 S67

  1. In Studio, create a Datahub configuration of type GraphQL. Under Security Settings, click Generate Key; each click adds a key, so several keys can be valid at once.
  2. Select the workspaces (asset folders) and the create/read/update/delete rights the endpoint may use. With no workspace, nothing is accessible.
  3. Send the key with each request as an apikey header, an X-API-Key header or an ?apikey= query parameter.
  4. Optional: disable introspection, or set what happens to related elements outside the workspace (fail the query, or null them out — the default).

Datahub Simple REST (API key or OAuth) S70

  • Delivery Settings tab: define or generate an API key, sent as a bearer token in a header with every request. The same key secures the MCP endpoint.
  • OAuth Access: allow chosen Pimcore users and roles to call the endpoint with tokens from the embedded OAuth 2.1 server. REST and MCP are separate audiences, so a token for one is refused by the other.

Studio Backend API (session) S60 S59

  • POST/pimcore-studio/api/login with credentials. With 2FA, the code follows on POST/pimcore-studio/api/login/2fa. POST/pimcore-studio/api/login/token logs in with a user token; POST/pimcore-studio/api/logout ends the session.
  • The OpenAPI file declares no security scheme S60. Calls rely on the session cookie set at login. Real-time updates go through a Mercure hub (POST/pimcore-studio/api/mercure/auth) S59 S60.
  • The API exists mainly to serve the Studio UI. Pimcore's Datahub docs separate the Studio API used by configuration panels from the endpoints meant for external systems S62 S70.

Embedded OAuth 2.1 authorization server (Studio Backend, experimental since 2026.3, off by default) S57 S11

  • Discovery: /.well-known/oauth-authorization-server (RFC 8414) and /.well-known/oauth-protected-resource{/path} (RFC 9728).
  • Flow: /pimcore-oauth/authorize sends the user to a consent screen in Studio, then /pimcore-oauth/token exchanges the code for tokens (authorization_code and refresh_token grants). PKCE S256 is required from every client; plain is refused.
  • Clients: pre-registered in config, optional Dynamic Client Registration (/pimcore-oauth/register, RFC 7591), or Client ID Metadata Documents. There is no client-credentials grant: tokens always act for a logged-in user. Machine access uses API keys or PATs instead.
  • The issuer must be the root of an origin; installations under a path prefix are not supported. The token and authorize endpoints have no rate limit.

MCP endpoints S56

  • Stateless pimcore_mcp firewall on /pimcore-mcp/. It tries, in order: the Studio session cookie, Bearer pmcp_… per-chat tokens (minted by the Pimcore AI agent server, SHA-256 hashed at rest, sliding expiry), Bearer <JWT> from the OAuth server, then static personal access tokens declared per username in YAML.
  • Unauthenticated calls get 401. When OAuth is on, the response carries a WWW-Authenticate header pointing at the protected-resource metadata.

WebDAV: any Pimcore user, with that user's asset permissions S31.

Core resources

Studio Backend API paths below are relative to https://{host}. They come from the OpenAPI file (version 2026.2): 683 paths, 815 operations (406 GET, 225 POST, 91 DELETE, 85 PUT, 8 PATCH) in 66 tags. 377 of these operations belong to Enterprise or optional bundles, so the routes available depend on what is installed S60.

ResourceEndpointsNotes
Assets (Studio API)GET/pimcore-studio/api/assets/{id} · PUT/pimcore-studio/api/assets/{id} · PATCH/pimcore-studio/api/assets · PATCH/pimcore-studio/api/assets/folder/{id} · DELETE/pimcore-studio/api/assets/batch-delete · POST/pimcore-studio/api/assets/{id}/clone/{parentId} · GET/pimcore-studio/api/assets/treeRead, update, batch patch (by IDs or by folder + filters), clone, tree listing with page/pageSize/pqlQuery S60
Uploads (Studio API)POST/pimcore-studio/api/assets/add/{parentId} (multipart file) · POST/pimcore-studio/api/assets/add-zip/{parentId} · POST/pimcore-studio/api/assets/{id}/replace · GET|POST /pimcore-studio/api/assets/exists/{parentId}Single upload, ZIP import, binary replacement, duplicate check S60
Renditions / downloads (Studio API)GET/pimcore-studio/api/assets/{id}/download · …/image/download/thumbnail/{thumbnailName} · …/image/download/format/{format} · …/image/stream/dynamic · …/video/stream/{thumbnailName} · …/video/thumbnail/{thumbnailName}/status · …/document/stream/pdf-preview · POST/pimcore-studio/api/assets/export/zip/assetOriginal, named/dynamic thumbnails, video transcodes and status, PDF previews, ZIP jobs S60
Thumbnail configs (Studio API)GET|POST /pimcore-studio/api/thumbnails/image/config… · …/thumbnails/video/config…CRUD on image and video pipelines S60
Metadata (Studio API)GET/pimcore-studio/api/assets/{id}/custom-metadata · GET/pimcore-studio/api/metadata/asset · POST|PUT|DELETE /pimcore-studio/api/metadata/predefined…Custom metadata, predefined metadata definitions S60
Metadata schema (Enterprise)…/pimcore-studio/api/bundle/amdcd/configs… (list, CRUD, import/export)Asset Metadata Class Definitions S60 S42
Search (Studio API)GET/pimcore-studio/api/search · POST/pimcore-studio/api/search/assets · POST/pimcore-studio/api/assets/grid · …/search/saved/configuration…Full-text and PQL search through the Generic Data Index, grid queries, saved searches S60 S43
Folders & treePOST/pimcore-studio/api/elements/{elementType}/folder/{parentId} · GET/pimcore-studio/api/elements/{elementType}/path · GET/pimcore-studio/api/assets/treeFolders are the main organising structure S60
TagsGET|POST|PUT|DELETE /pimcore-studio/api/tags… · POST/pimcore-studio/api/tags/assign/{elementType}/{id}/{tagId} · POST/pimcore-studio/api/tags/batch/{operation}/{elementType}/{id}Tag tree and assignment, batch on children S60
VersionsGET/pimcore-studio/api/versions/{elementType}/{id} · GET/pimcore-studio/api/versions/{id}/asset/download · POST/pimcore-studio/api/versions/{id} (publish)Version history and restore S60
Properties, notes, schedules…/properties… · …/notes/{elementType}/{id} · …/schedules/{elementType}/{id}Inheritable properties, Notes & Events, scheduled actions S60
Dependencies & usageGET/pimcore-studio/api/dependencies/{elementType}/{id} · GET/pimcore-studio/api/elements/usage/{elementType}/{id} · POST/pimcore-studio/api/elements/usage/replace/{elementType}/{id}Where an asset is used; replace all references S60
WorkflowsGET/pimcore-studio/api/workflows/details · POST/pimcore-studio/api/workflows/actionWorkflow state and transitions S60
Users / roles28 User Management and 12 Role Management operations, e.g. GET/pimcore-studio/api/roles, GET|PUT|DELETE /pimcore-studio/api/role/{id}, and the matching /pimcore-studio/api/user… pathsUsers, roles, permissions S60
Rights / permissionsGET/pimcore-studio/api/elements/{elementType}/context-permissions/ · edit-lock endpointsNo dedicated usage-rights resource S60
Portals & collections (Enterprise)…/pimcore-studio/api/bundle/portal-engine/collection… (create, list, share, tree items) · …/wizard/create-portalPortal Engine admin operations S60
Direct Edit (Enterprise)POST…/bundle/direct-edit/assets/{id}/generate-link · …/confirm-upload · …/resolve-conflict · GET…/statusLocal-editing sessions S60
Assets (GraphQL)Queries getAsset(id), getAssetFolder(id), getAssetListing(ids, first, after, sortBy, sortOrder, filter); mutations createAsset, updateAsset, deleteAsset(id|fullpath)Fields depend on the endpoint schema. Binary data is sent base64-encoded in input.data S64 S65
Renditions (GraphQL)fullpath(thumbnail: "name", format:, deferred:) on asset fieldsImage and video thumbnails by configuration name S64
Assets (Simple REST, Enterprise)tree-items, search, get-element, download-asset under /pimcore-datahub-webservices/simplerest/Read-only. The first three answer from OpenSearch/Elasticsearch without hitting the database; download-asset streams the original or a configured thumbnail S69 S70
Webhooks config (Enterprise)GET|PUT /pimcore-studio/api/bundle/data-hub-webhooks/config/{name} · POST…/config/test-subscribersConfiguration through the Studio API; there is no public subscription API S60

Exact per-config Simple REST paths and parameters are documented in each instance's Swagger UI, which was not reachable without an instance S69.

Data model

  • Elements: Assets, Data Objects and Documents are the three element types. Each element has an integer ID, a full path in its tree (/folder/file.jpg), a type and timestamps S95 S60.
  • Asset types: image, video, audio, document, text, archive, folder and unknown (the default list in webhook schemas) S74. GET/pimcore-studio/api/assets/types returns the installed list S60.
  • Metadata: a list of entries (name, input type, language, data), localizable, with fallback to the unlocalized value (e.g. addMetadata("title", "input", "…", "en")) S32. The full list of core metadata types is not stated on that page: Unknown. Enterprise class definitions add structured schemas and more data types S42. Embedded EXIF/IPTC/XMP is exposed read-only S26.
  • Files & renditions: one binary per asset in Flysystem storage. Renditions ("thumbnails") are generated from named configurations, on demand or deferred, and stored in their own storage S33 S27.
  • Taxonomy: hierarchical tags (ID, name, parentId, idPath), inheritable properties and folder paths S35.
  • Relations: data objects link to assets through relation fields. Dependencies are tracked both ways S60 S95.
  • Versions: serialized snapshots with optional notes S34 S32.

Search & querying

  • PQL (Studio API pqlQuery, Copilot filters): comparisons, LIKE with */? wildcards (case-insensitive), NULL/EMPTY, AND/OR with brackets, relation filters such as main_image:Asset.type = "image", raw QUERY('…') S43.
  • GraphQL: filter takes a JSON condition ($like, $and, $or, …) in Pimcore's webservice filter syntax; sortBy/sortOrder; totalCount S66 S64.
  • Simple REST: fulltext_search (OpenSearch simple_query_string), query_string_query for field filters, legacy JSON filter, order_by (string or JSON with unmapped_type), and aggregations for facets configured per endpoint. Without order_by, results come by relevance (full-text) or by system.id S71 S70.
  • Max page size: Studio API: Not public (no maximum stated in the spec). Simple REST MCP tools clamp to 1–200 S72. Deep paging through page_cursor / search_after S71.
  • Semantic search through embeddings (Enterprise, experimental), behind a dedicated permission S11 S41.

Uploads & binaries

  • Studio API: multipart/form-data upload with a file field (and optional assetType) to /pimcore-studio/api/assets/add/{parentId}. ZIP import and binary replacement have their own endpoints S60. Chunked or resumable upload: Not public (no such endpoint in the spec).
  • GraphQL: createAsset / updateAsset take the file as base64 in input.data. The parent must be in a workspace with create rights S65.
  • WebDAV: PUT/GET through any WebDAV client S31.
  • Downloads: public assets and thumbnails are plain URLs served by the web server (with optional CDN prefixes). Protected folders need a custom controller S30 S33. Studio API download and stream endpoints need a session S60. Simple REST download-asset only hands out variants allowed by the endpoint configuration S70.
  • Presigned URLs: Not public (none documented).
  • Server upload limits follow PHP settings (≥ 100 MB recommended) S36.

Events & webhooks

  • Datahub Webhooks (Enterprise) S73 S74 S75 S76 S77:
    • Events: pimcore.asset.postAdd (POST), postUpdate (PUT), postDelete (DELETE), postUpdateFailure, postDeleteFailure, and the same for data objects and documents; workflow.entered, workflow.completed (PUT).
    • Configured in the Studio UI per Datahub configuration: asset types, workspaces, optional binary data (original or a thumbnail, base64 in data64), subscriber URLs, custom headers (e.g. an auth header). A test button checks reachability.
    • Payload: general (eventName, timestamp, subjectType, versionOnly) and subject (id, path, type, mimeType…), plus workflowData for workflow events.
    • Delivery goes through a Symfony Messenger queue and is attempted once: a subscriber that was down does not get the event later. Failures appear in the configuration's Logs tab. No payload signature is documented. Auto-saves never trigger webhooks.
  • Server-side events: Pimcore and Symfony event listeners (e.g. asset pre/post save) for custom code S74 S59.
  • Real-time UI updates: Mercure server-sent events S59.
  • Workflow Automation (Enterprise) exports n8n blueprints built from GraphQL and webhook configurations S79.

Limits & quirks

  • Rate limits apply to the Studio API and MCP only: 500/min and 3,000/min per IP by default. Behind a proxy, trusted proxies must be configured or all users share one bucket. Multi-server setups need a shared cache (e.g. Redis) for the limiter S58.
  • Assets are public by URL by default: an API permission model does not protect a file's direct URL unless protected folders are set up S30.
  • GraphQL API keys in the query string are supported, so keys can end up in access logs. Header-based keys (apikey, X-API-Key) are also accepted S62 S67.
  • "Skip Permission Check" disables workspace checks entirely for a GraphQL endpoint S63.
  • Simple REST is eventually consistent: it serves the search index, so new configuration changes need re-indexing. binaryData links can point to variants no longer published until re-indexing. For SVGs, a non-rasterizing thumbnail exposes the original S70.
  • GraphQL output cache (off by default, 30 s default lifetime when on) can serve stale data S62.
  • Datahub config storage: YAML files are only re-read in debug mode, so production changes must be deployed S68.
  • OAuth server is experimental: configuration keys may change between minor versions S57.
  • Studio API is shaped around the UI (grids, perspectives, widgets), declares no security scheme in OpenAPI, and depends on Mercure and the Generic Data Index S60 S59.
  • Enterprise source is private: Simple REST, Webhooks, Portal Engine, Direct Edit and Copilot repositories are not public on GitHub S90.

SDKs, tools & code samples

ToolLanguageStatusNotes
Pimcore PHP APIPHP (in-process)Official, currentPimcore\Model\Asset, listings, metadata, tags S32 S35
Studio UI SDKTypeScript/ReactOfficialPlugin SDK with RTK Query clients generated from the OpenAPI file S60
GraphQL Playground / ExplorerWebOfficialOpened from each Datahub configuration S62
Swagger UI (Studio, Simple REST)WebOfficialPer instance S59 S70
pimcore/skillsMarkdownOfficial, public repoAgent skill for Pimcore developers documenting Studio Backend endpoints (OpenAPI translation keys, tags) S90
Remote client SDKs (JS, Python, PHP HTTP client)—None official found S90
Direct Edit ClientElectron (Windows, macOS)Official, EnterpriseDesktop helper S50

Changelog of the API

DateChange
2026-09-292026.3: embedded OAuth 2.1 authorization server (experimental); Simple REST accepts OAuth tokens on REST and MCP; legacy /admin/bundle/* routes of ApplicationLogger, CustomReports and SEO removed; legacy portal frontend deprecated (removal 2027.1) S11 S13
2026-07-082026.2: optional published argument for Datahub data object mutations; CDN invalidation events; issues consolidated in platform-version S10 S13
2026-04-082026.1: Admin UI Classic and all classic admin controllers removed (Studio API only); Datahub adapters move to pipeline-based schemas (legacy read-only, removal 2027.1); unified 2026.1.x module versioning; PHP 8.4+, Symfony 7 S9 S12
2025-12-092025.4 (LTS): experimental MCP server support S8 S13
2025-04-302025.1 (Pimcore 12): POCL licence; product registration required; Datahub SQL condition field and merge operator removed; timezone on date fields S6 S13

Stored API specs

No public machine-readable spec storedSpecs README & provenance
Search the wiki