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
- Rate limit (details in section Limits & quirks)
- None documented (API throttling on the 11.2 roadmap, not yet scheduled)
- Webhooks (details in section Events & webhooks)
- none (API Webhooks plugin = user-triggered outbound POST buttons)
- Pagination (details in section At a glance)
- offset (do_search fetchrows "offset,limit" returns total + data; offset param)
- API spec (details in section At a glance)
- none published (KB-described per-instance OpenAPI generator absent from 11.0 code)
At a glance
API styles
One HTTP endpoint,
/api/, takes GET or POST. A function parameter names one of the API "bindings", followed by its parameters. Montala calls it "RESTful" and JSON-returning S1 S30. Its own developer notes say it leans "towards a custom JSON-RPC" S10. Separate IIIF Image and Presentation APIs live under /iiif/ S9Base URL(s)
Current version(s) & deprecations
One unversioned API, called "API v2" when it arrived in 7.9 (2016-09-16). It replaced the older
api_core / api_search plugins S22. Montala states it cannot break backwards compatibility because the API has no versioning S10. The product release is 11.0 (2026-06-29); 11.1 is planned for 2027-02-23 S21 S23Auth methods
Token lifetime / refresh
Private user keys have no documented expiry. Session keys are derived from the user's current login session (HMAC of session value and private key in the code), so they last as long as that session; the exact lifetime is Not public S7 S15. File URLs returned by
get_resource_path stay valid for 24 h by default ($api_resource_path_expiry_hours) S6Scopes / permission model
Official spec
None published. A Knowledge Base article says that "from version 11" an OpenAPI document is generated per instance at
/api/openapi.php with zircote/swagger-php S10. Unverified On 2026-10-29 no openapi.php and no OpenAPI annotations existed in the 11.0 release, trunk or GitHub master S15 S17. Nothing is archived on DAM Wiki; see API spec downloadsRate limits
None documented. "API throttling" is a roadmap item for 11.2 (status "Waiting for go-ahead"), and lockout after repeated failed API logins is under scoping for 11.3 S23
Pagination
Webhooks / events
Official SDKs
Authentication
- Get the key: each user has a private API key on their account page. An admin can also copy it from Admin → Users → {user} ("Private API Key") S1 S80. On a self-hosted system,
$enable_remote_apis = falseinconfig.phpturns off remote API access and hides the keys and the test tool; only native mode keeps working S1. - Build the query string:
user={username}&function={binding}¶m1=…(or named parameters);- values are percent-encoded;
- optional parameters can be left out when passed by name;
authmode, if present, must be the last parameter S1.
- Sign:
sign = hex(sha256(private_key + query_string)). Send it assignin the GET query, or POSTquery,signanduseras form fields S1. - Session-key variant: POST
login(username, password)to get a session API key. It must be POSTed so the password stays out of URLs and logs. Then sign with it and sendauthmode=sessionkeyS7 S1. - Native mode (
authmode=native): uses the browser login cookie, through theapi()JavaScript helper. Since 10.2 only functions suited to browser use are allowed, and state-changing calls need the CSRF token S1 S11. - Integration sign-in (undocumented): development notes mention
$api_issue_valid_destinations, a list of allowed callback destinations that lets connectors obtain credentials after a user signs in. It was added for Canva SSO support (developed by SpotDev, 2026-07) and extended for CI-HUB (2026-10-26) S24. Unverified The flow itself is not documented publicly. The Canva and LinkrUI connectors describe "Grant access" / SSO sign-in from the user's side S77 S78.
Core resources
All calls go to GET|POST https://{host}/api/?function={name}…. The table below groups the functions listed in the API reference (93 entries including IIIF and plugin functions, 2026-10-29) S1. Trunk defines 76 core bindings in include/api_bindings.php (11.0 release: 75) S15.
| Resource | Functions (function=) | Notes |
|---|---|---|
| Assets ("resources") | create_resource, copy_resource, delete_resource, get_resource_data, put_resource_data, get_resource_field_data, update_resource_type, get_resource_types, get_resource_access, get_edit_access, resource_file_readonly, update_resource_lock (11.1) | Integer ref IDs. create_resource can create the resource, upload a file and set metadata in one call S1 S22 S24 |
| Files & renditions | upload_file, upload_file_by_url, upload_multipart, replace_resource_file, validate_upload_url, get_resource_path, get_resource_all_image_sizes, add_alternative_file, get_alternative_files, delete_alternative_file | get_resource_path returns temporary URLs for a size code (e.g. scr) or the original; it also accepts an array of IDs S4 S5 S6 |
| Metadata & schema | update_field, get_field_options, get_nodes, get_node_id, set_node, add_resource_nodes, add_resource_nodes_multi, get_resource_type_fields, create_resource_type_field, toggle_active_state_for_nodes, get_data_by_field | Fixed-list values are nodes: look up node IDs, then update_field with nodevalues=true S1 |
| Search | do_search, search_get_previews | ResourceSpace search syntax; search_get_previews adds preview URLs for the requested sizes S2 S3 |
| Collections | get_user_collections, create_collection, save_collection, delete_collection, get_collection, add_resource_to_collection, remove_resource_from_collection, collection_add_resources, collection_remove_resources, delete_resources_in_collection, get_collections_resource_count, search_public_collections, get_featured_collections, reorder_featured_collections, show_hide_collection, send_collection_to_admin, get_resource_collections | S1 |
| Relations | get_related_resources, update_related_resource, relate_all_resources | S1 |
| Users & groups | login, checkperm, get_users, get_users_by_permission, new_user, save_user (10.7), mark_email_as_invalid, get_profile_image, get_processing_message | No group-management calls are listed. "Find users by user ref" is under scoping for 11.3 S1 S21 S23 |
| Comments & logs | get_resource_comments, delete_comment, get_resource_log, resource_log_last_rows | Comments and reports calls added in 11.0 S1 S21 |
| Rights & consent | consentmanager_* (create, get, update, delete, link/unlink, batch link, save file, by collection), licensemanager_get_licenses | Need the Consent Manager / License Manager plugins S1 |
| Sharing | delete_access_keys | No call to create external shares is listed S1 |
| System & reporting | get_system_status (health checks with severity), get_daily_stat_summary, get_reports, do_report | S8 S1 |
| Messages / UI | get_user_message, send_user_message, save_tab, delete_tabs, reorder_tabs, get_dash_search_data | S1 |
| AI | faces_set_node | AI Faces plugin S1 |
| Workflows | No API call to define workflows. The workflow state is the archive value on resources and in searches | S2 S68 |
| IIIF | /iiif/{identifier}/manifest, /iiif/{identifier}/canvas/{n}, /iiif/image/{ref}/full/max/0/default.jpg | Presentation 3.0 (2.1 by default unless $iiif_version = 3.0) and Image API level 0; served as $iiif_userid S9 |
Data model
- A resource has an integer
refand a resource type. Search results return core columns (ref,resource_type,archive,access,file_extension,creation_date,file_checksum,hit_count…) and indexed field values asfield{N}keys. The exact payload depends on configuration S2. - Metadata fields ("resource type fields") have integer IDs and shorthand names. Since 10.2 a field can apply to several resource types S1 S21.
- Fixed-list options (check boxes, drop-downs, category trees, dynamic tags) are nodes with their own IDs. Since 10.0, free text is stored and searched through the node model as well S1 S21.
- Files: one original per resource plus alternative files. Previews come in size codes (e.g.
thm,pre,scr,col) under a scrambled filestore path S3 S6 S20. - Workflow / visibility:
- The full database schema (tables
resource,resource_node,node,collection,api_log…) is documented publicly S10.
Search & querying
do_search(search, restypes, order_by, archive, fetchrows, sort, offset)S2:searchuses the standard ResourceSpace syntax: keywords, special search terms,field:valuematching, date ranges such asdatefield:rangestart2019-01-01end2019-01-07, and partial dates2019|01|nn;order_bytakes relevance, popularity, rating, date, colour, title, resourceid, random, status and others;archivefilters by workflow state.
- Paging:
fetchrows="offset,limit"returnstotalplusdata. Without it, all matching rows come back (fetchrows=-1) S2 S3. Unverified The two search references disagree on when this arrived: 10.3 fordo_search, 10.2 forsearch_get_previewsS2 S3. - Facets / aggregations: none documented in the API (Unknown). Faceted refining exists in the UI (Refine results plugin) S99.
- Smart search: CLIP natural-language and visual search is a UI plugin; no dedicated API binding is documented (Unknown) S56.
- Basic-search limit: since 10.1, basic search reads only the first 500 characters of long text fields S21.
Uploads & binaries
- Two-step pattern:
create_resource(optionally with a file URL and metadata), then attach the file with one of S1 S4 S5:upload_multipart: HTTPmultipart/form-data; the file part is not part of the signature;upload_file_by_url: the server fetches a remote URL, which must be allowed by$api_upload_urls;upload_file.
upload_multipartresponses S4:- HTTP 204 on success;
- 413 when the file is too large (server upload limit);
- 400 for a duplicate, when checksums are enabled;
- 500 for other errors, with a body
{status: "fail", data: {message}}. - Since 10.6 it can also replace alternative files and previews S21.
- Chunked / resumable: the web UI chunks large uploads ("no restriction on maximum file size") S30. A chunked API flow is not documented (Unknown). The 11.0 code includes a tus-php configuration (
include/tusconfig.php, tied to the user session), which suggests the browser uploader uses the tus resumable protocol S15. Unverified This is inferred from the code; no tus endpoint is documented for API clients. - Downloads:
get_resource_path(ref, size, generate, extension, page, watermarked, alternative, write_metadata)returns a temporary download URL (24 h by default), or an array of URLs when given several IDs S6. - Bulk / server-side ingestion: StaticSync hot folders and SFTP drop folders (hosted) S64 S27.
Events & webhooks
- No event subscription API. The API Webhooks plugin (10.1) is configured in
config.php($api_webhooks_urls). It shows custom buttons on the resource edit page. When a user clicks one, the server saves the form, then POSTs the resource ID to the configured URL. An optionalhashsecret adds a SHA-256 hash of the ID so the receiver can check the request S12 S21. - Only the
editlocation is supported. Retries and payload schema: Not public S12. - Polling:
resource_log_last_rowsreturns recent resource log rows, so a remote system can poll for changes S1 S22. - Notifications: watched searches and email notifications (UI) S95.
Limits & quirks
- Errors can return HTTP 200: Montala notes that failed calls may still return status 200; check the payload S10.
- Signing order matters: the signature covers the exact query string.
sign,authmodeandprettyare stripped before verification, andauthmodemust come last S1 S15. Booleans may need to be sent as1/0S4. - Disabled API:
$enable_remote_apis=falsereturns HTTP 403 for non-native calls S15 S1. - API log (11.1): external userkey requests are logged in
api_log; retention 14 days by default, minimum 7; specific usernames can be excluded S1 S24. - No rate limiting today: throttling is still a roadmap item, so self-hosters need their own web-server limits S23.
- Behaviour depends on configuration: returned fields, previews and permissions all follow the signing user and the instance's plugins and configuration S2 S8.
- Reference error: on the API index, the
update_resource_lockentry links to thevalidate_upload_urlpage S1. - Typesense search (11.0, experimental) does not apply permissions. Montala advises using it only where every user may see every resource S63.
SDKs, tools & code samples
| Tool | Language | Maintainer | Status |
|---|---|---|---|
| API test tool (Admin → System) | Generates PHP / cURL | Montala | Built in S1 |
| Code samples in the reference (GET, POST, session key, metadata updates) | PHP, Perl, bash/cURL | Montala | S1 S4 |
api() JavaScript helper (native mode) | JavaScript | Montala | For in-app use and plugins S11 |
api/example.php in the source tree | PHP | Montala | S15 |
| WordPress plugin (shortcodes, media library mapping) | PHP | Codecide, funded by ADRA International; distributed through the ResourceSpace KB | v1.0.10 S80 |
| Drupal 11 media-library sync module | PHP | Distributed through the ResourceSpace KB | S81 |
urban-brussels/resourcespace-api | PHP | Community (Packagist) | 74 downloads on 2026-10-29 S101 |
rkw/rkw-resourcespace (TYPO3 extension) | PHP | Community (Packagist) | S101 |
| ResourceSpace MCP plugin / servers | PHP; TypeScript | Magnolia Tech Services (third party) | See Integrations S93 S94 |
| No official Python, JavaScript, .NET or Java SDK | — | — | None found on PyPI or npm S101 |
Changelog of the API
| Date | Change | Source |
|---|---|---|
| 2027-02-23 (planned, 11.1) | "MCP API interface" (scoping); get_system_status to report recent uploads | S23 |
| 2026-10-26 (Labs, for 11.1) | Several callback URLs per system in $api_issue_valid_destinations (CI-HUB production and test) | S24 |
| 2026-10-13 (Labs, for 11.1) | New update_resource_lock() call (needed for the CI-HUB integration) | S24 |
| 2026-10-12 (Labs) | Automated tests for every API binding | S24 |
| 2026-09-15 (Labs, for 11.1) | API usage logging and reporting (api_log table) | S24 S1 |
| 2026-07-15 / 16 (Labs) | $api_issue_valid_destinations becomes a config option; Canva added for SSO | S24 |
| 2026-06-29 (11.0) | New calls for comments and reports; PHP 8.2 minimum | S21 |
| 2025-10-06 (10.7) | new_user(), save_user(); get_resource_path gets write_metadata | S21 S6 |
| 2025-05-27 (10.6) | upload_multipart() extended to alternative files and previews | S21 |
| 2024-12-09 (10.5) | get_resource_access(), checkperm(), Consent Manager calls | S21 |
| 2024-01-24 (10.3) | IIIF updated to 3.0; get_system_status severity values; fetchrows offset/limit on do_search | S21 S8 S2 |
| 2023-07-24 (10.2) | Native mode restricted to browser-suitable functions; CSRF token required for state changes | S1 S11 |
| 2023-02-13 (10.1) | API Webhooks plugin; get_users_with_permission() (listed today as get_users_by_permission) | S21 S1 |
| 2022-02-12 (9.8) | get_nodes() | S21 |
| 2016-09-16 (7.9) | "API v2": signed requests with per-user private keys; old API plugins removed | S22 |