DAM Wiki

ResourceSpace API

Montala Limited · Watchfield, Oxfordshire, UK · Founded 2006 · independentVerified 2026-10-29 · 101 sources
  • SaaS
  • On-premise
  • Mid-market
  • REST API
  • Webhooks (Partial)
  • SAML · LDAP SSO
Complete · 7 of 7 pages
101sources
0API specs
10-29verified 2026
Official website ↗ResourceSpace alternatives →

In brief

From this page’s summary fields, verified 2026-10-29. Sources in each section.
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/ S9
Base URL(s)
https://{host}/api/ on every installation: self-hosted, {name}.free.resourcespace.com, or a Montala-hosted domain S1 S28. IIIF: https://{host}/iiif/… (needs a web-server rewrite rule) S9. No central multi-tenant API host
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 S23
Auth methods
authmode=userkey (default): every request is signed with SHA-256 over the user's private API key plus the query string. sessionkey: the key comes from login(). native: browser cookie plus CSRF token, for in-app JavaScript S1 S7 S11
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) S6
Scopes / permission model
No scopes. Each call runs as the signing user, with that user group's permissions, search filters and access levels S1. A typical pattern is a dedicated user restricted by filters, for example for IIIF or the Drupal sync S9 S81
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 downloads
Rate 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
do_search / search_get_previews: fetchrows as a row cap, or as "offset,limit" (10.2/10.3+), which returns {total, data}. do_search also has an offset parameter S2 S3
Webhooks / events
No outbound event webhooks. The API Webhooks plugin (10.1) adds edit-page buttons that POST the resource ID to a configured URL, with an optional SHA-256 hash S12 S21. resource_log_last_rows lets clients poll for recent changes S1 S22
Official SDKs
None. The in-app API test tool (Admin → System) runs calls and generates PHP and cURL code S1. Community PHP wrappers exist on Packagist S101
Sandbox / trial access
Free 10 GB cloud instance (up to 10 users), or a free self-hosted install (Docker or LAMP) S28 S18. Paid plans also get a ResourceSpace Labs instance on the development branch S25. API access appears in every paid package S27

Authentication

  1. 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 = false in config.php turns off remote API access and hides the keys and the test tool; only native mode keeps working S1.
  2. Build the query string:
    • user={username}&function={binding}&param1=… (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.
  3. Sign: sign = hex(sha256(private_key + query_string)). Send it as sign in the GET query, or POST query, sign and user as form fields S1.
  4. 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 send authmode=sessionkey S7 S1.
  5. Native mode (authmode=native): uses the browser login cookie, through the api() JavaScript helper. Since 10.2 only functions suited to browser use are allowed, and state-changing calls need the CSRF token S1 S11.
  6. 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.

ResourceFunctions (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 & renditionsupload_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_fileget_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 & schemaupdate_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_fieldFixed-list values are nodes: look up node IDs, then update_field with nodevalues=true S1
Searchdo_search, search_get_previewsResourceSpace search syntax; search_get_previews adds preview URLs for the requested sizes S2 S3
Collectionsget_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
Relationsget_related_resources, update_related_resource, relate_all_resources S1
Users & groupslogin, checkperm, get_users, get_users_by_permission, new_user, save_user (10.7), mark_email_as_invalid, get_profile_image, get_processing_messageNo group-management calls are listed. "Find users by user ref" is under scoping for 11.3 S1 S21 S23
Comments & logsget_resource_comments, delete_comment, get_resource_log, resource_log_last_rowsComments and reports calls added in 11.0 S1 S21
Rights & consentconsentmanager_* (create, get, update, delete, link/unlink, batch link, save file, by collection), licensemanager_get_licensesNeed the Consent Manager / License Manager plugins S1
Sharingdelete_access_keysNo call to create external shares is listed S1
System & reportingget_system_status (health checks with severity), get_daily_stat_summary, get_reports, do_report S8 S1
Messages / UIget_user_message, send_user_message, save_tab, delete_tabs, reorder_tabs, get_dash_search_data S1
AIfaces_set_nodeAI Faces plugin S1
WorkflowsNo 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.jpgPresentation 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 ref and 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 as field{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:
    • archive holds the workflow state: 0 active, 1 pending archive, 2 archived, 3 deleted, -1 pending review, -2 pending submission, plus custom states from the Advanced workflow plugin S2 S68;
    • access sets visibility: open, restricted or confidential S100.
  • 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:
    • search uses the standard ResourceSpace syntax: keywords, special search terms, field:value matching, date ranges such as datefield:rangestart2019-01-01end2019-01-07, and partial dates 2019|01|nn;
    • order_by takes relevance, popularity, rating, date, colour, title, resourceid, random, status and others;
    • archive filters by workflow state.
  • Paging: fetchrows="offset,limit" returns total plus data. Without it, all matching rows come back (fetchrows=-1) S2 S3. Unverified The two search references disagree on when this arrived: 10.3 for do_search, 10.2 for search_get_previews S2 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: HTTP multipart/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_multipart responses 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 optional hash secret adds a SHA-256 hash of the ID so the receiver can check the request S12 S21.
  • Only the edit location is supported. Retries and payload schema: Not public S12.
  • Polling: resource_log_last_rows returns 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, authmode and pretty are stripped before verification, and authmode must come last S1 S15. Booleans may need to be sent as 1/0 S4.
  • Disabled API: $enable_remote_apis=false returns 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_lock entry links to the validate_upload_url page 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

ToolLanguageMaintainerStatus
API test tool (Admin → System)Generates PHP / cURLMontalaBuilt in S1
Code samples in the reference (GET, POST, session key, metadata updates)PHP, Perl, bash/cURLMontala S1 S4
api() JavaScript helper (native mode)JavaScriptMontalaFor in-app use and plugins S11
api/example.php in the source treePHPMontala S15
WordPress plugin (shortcodes, media library mapping)PHPCodecide, funded by ADRA International; distributed through the ResourceSpace KBv1.0.10 S80
Drupal 11 media-library sync modulePHPDistributed through the ResourceSpace KB S81
urban-brussels/resourcespace-apiPHPCommunity (Packagist)74 downloads on 2026-10-29 S101
rkw/rkw-resourcespace (TYPO3 extension)PHPCommunity (Packagist) S101
ResourceSpace MCP plugin / serversPHP; TypeScriptMagnolia 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

DateChangeSource
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

Stored API specs

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