DAM Wiki

MediaValet API

MediaValet Inc. · Vancouver, BC; US HQ Menlo Park, CA, Canada · Founded 2010 · PE-backed (STG, acquired 2024-04-02; delisted from TSX)Verified 2026-10-01 · 157 sources
  • SaaS
  • Mid-market
  • REST API
  • Partial OpenAPI
  • Webhooks
  • SAML · OIDC SSO
Complete · 7 of 7 pages
157sources
11API specs
10-01verified 2026
Official website ↗MediaValet alternatives →

Scope: the public REST API of the MediaValet SaaS DAM ("NextGen API"), its webhook service SkyHOOK and the Unify Integrations API, all published through an Azure API Management (APIM) gateway at api.mediavalet.com. Everything below comes from the public Postman documentation, the public developer-portal data and unauthenticated probes; no authenticated call was made.

At a glance

API styles
REST/JSON over HTTPS with hypermedia _links; JSON Patch (RFC 6902) for partial updates S1. No GraphQL found. Vendor marketing: "RESTful JSON", "Authenticated: Basic, OAuth 2" S90
Base URL(s)
API: https://api.mediavalet.com (single global host; no tenant appears in the host or path of any documented request — how the library is selected is not documented, presumably from the user's token Unverified) S1 S3. SkyHOOK: https://api.mediavalet.com/skyhook; Unify: https://api.mediavalet.com/integrations S8 S12. Identity: https://login.mediavalet.com (issuer https://iam.mediavalet.com) S1 S14. Asset Picker: https://assetpicker.mediavalet.com S1. The APIM export names an http:// server too, but the gateway is used over HTTPS S12
Current version(s) & deprecations
Header-based versioning x-mv-api-version: 1.2, 1.1, 1.0 (default when the header is absent) S1. The Unify API has APIM inject 1.2 automatically S12. Deprecated (2024-05-22): stream / streamLoDef asset fields (Azure Media Services retirement) → streamingManifest S1
Auth methods
OAuth 2.0 / OIDC authorization code flow (documented, recommended) and resource owner password grant (documented for non-interactive use; client authenticated with HTTP Basic client_id:client_secret) S1 S23; plus an APIM subscription key on every call (Ocp-Apim-Subscription-Key header or subscription-key query) S12 S15. Client credentials: "coming soon" per docs Unverified (see Authentication)
Token lifetime / refresh
Access token expires_in: 3600 (1 h) in all documented samples; authorization code valid 60 s; refresh tokens issued with scope offline_access, rotated (a new refresh_token is returned on refresh) S1. Refresh-token lifetime: Not public
Scopes / permission model
Required scopes openid api; offline_access optional S1. No fine-grained API scopes: requests run with the MediaValet user's role/group permissions; docs and Help Center require an administrator account (or admin approval) to use the API S5 S21. Since v1.2, an authenticated user lacking permission gets 403 instead of 401 S1
Official spec
Public Postman collection (v2.0.0 schema, 362 requests) behind docs.mediavalet.com S1 S2; per-operation lists in the APIM developer portal (359 NextGen + 5 SkyHook + 12 Unify operations) S9 S10 S11; APIM OpenAPI 3.0.1 exports are downloadable but contain no paths (servers + security schemes only) S12. Archived copies on DAM Wiki: API spec downloads
Rate limits
APIM "products": Developer Plan ("limited amount of daily requests", proof-of-concept) and Enterprise Plan ("near unlimited", webhooks, dedicated testing library) S6 S13. Numeric quotas: Not public (shown only under the subscriber's profile — Behind login). MediaValet Direct desktop tool: 500 assets/min S36
Pagination
offset (default 0) + count (default 50) query parameters on list endpoints; response envelope RecordCount { TotalRecordsFound, StartingRecord, RecordsReturned } S1; POST/assets/search takes offset/count/includeTotalCount in the body S2. Maximum page size: Not public
Webhooks / events
SkyHOOK: subscriptions managed by API (/skyhook/subscriptions), 8 event types, CloudEvents 1.0 envelopes, delivery to your HTTPS endpoint or to your own Azure Event Grid topic; endpoint validated by the CloudEvents abuse-protection handshake (HTTP OPTIONS) S1 S24 S26. "Enterprise level": webhooks are listed as an Enterprise Plan feature S6
Official SDKs
None. One official C#/.NET 8 sample (large-file upload) on GitHub S16; no packages on npm, NuGet, PyPI or Packagist S18
Sandbox / trial access
No public sandbox; developer accounts are only for existing customers/partners with access to a MediaValet library S5. Enterprise Plan includes a dedicated testing library S6

Authentication

Getting credentials S5 S21 S22

  1. Have a user (ideally admin) account in the MediaValet library to integrate with.
  2. Register at the developer portal (developer.mediavalet.com, Azure APIM) and subscribe to a plan under Products — the Developer Plan is included in the MediaValet subscription; the Enterprise Plan goes through the account manager.
  3. MediaValet Support e-mails you to collect the library URL, redirect URIs to whitelist and (if you are not an admin) an admin's approval; it then issues client_id / client_secret and activates the primary/secondary subscription keys visible in your portal profile.
  4. Postman callback URLs (https://www.getpostman.com/oauth2/callback, https://oauth.pstmn.io/v1/callback, https://oauth.pstmn.io/v1/browser-callback) are whitelisted by default; other redirect URIs must be whitelisted by Support. Credentials may be shared by several users of the same library working on the same integration S22.

Endpoints S1 S14

EndpointURL
AuthorizeGEThttps://login.mediavalet.com/connect/authorize
TokenPOSThttps://login.mediavalet.com/connect/token (form-encoded; client_secret_basic or client_secret_post)
Discoveryhttps://login.mediavalet.com/.well-known/openid-configuration (also lists userinfo, revocation, introspection, device-authorization, CIBA and PAR endpoints)

Authorization code flow S1: /connect/authorize?client_id=…&response_type=code&scope=openid api&redirect_uri=…&state=… → user signs in on MediaValet's login page → code returned to the redirect URI → server-side POST/connect/token with grant_type=authorization_code, code, redirect_uri, client_id, client_secret → response {id_token, access_token, expires_in: 3600, token_type: "Bearer"}. Use Authorization: Bearer <token> on API calls.

Resource owner password grant S1 S16: POST/connect/token with grant_type=password, username, password (the user's DAM login), scope=api (or openid api), and Authorization: Basic base64(client_id:client_secret). MediaValet discourages it for security reasons but calls it the preferred option for non-interactive integrations; the official GitHub sample uses only this flow.

Refresh S1: grant_type=refresh_token + client credentials; returns new access_token, id_token and a new refresh_token.

Every API request also needs the APIM subscription key: without it the gateway answers 401 with WWW-Authenticate: AzureApiManagementKey … name="Ocp-Apim-Subscription-Key" S15; the Unify API description states both the IAM JWT and the subscription key are mandatory S12.

Unverified Grant-type inconsistencies. The docs' parameter table lists only authorization_code and refresh_token as grant types, the same page documents the password grant, the Help Center lists "Auth Code + Resource Owner Password" and says Client Credentials is "COMING SOON" S1 S23, while the public OIDC discovery document advertises client_credentials, implicit, device_code, CIBA and token-exchange grants and PKCE (S256, plain) S14. Discovery reflects the identity server's capabilities, not necessarily what is enabled for API clients — treat client credentials and PKCE as not officially supported until documented. Scopes advertised in discovery include api:service_principal, iam.admin and iam.provisioning (undocumented) S14.

Core resources

Paths are relative to https://api.mediavalet.com. Counts are APIM operations (NextGen API) per first path segment S9; examples from the Postman collection S2.

ResourceEndpointsNotes
Home / discoveryGET/ (JSON home document of endpoints available to the user), POST/bulkHypermedia entry point S2
Assets (53 ops)GET/assets, POST/assets/search, POST/assets/search/basic, POST/assets/search/duplicates, GET/PATCH/PUT/DELETE /assets/{assetId} (isHardDelete, includeSoftDeleted), /assets/{id}/attributes, /keywords, /categories, /comments, /rating, /history, /versions, /renditions[/{renditionKindId}], /relatedassets, /autotags, /faces, /checkOut, /clip, /videoIntelligence/*, /videoTranscript, /downloaded, /viewed; POST/assets/undeleteValidateSoft delete by default; duplicates searched by MD5 and optionally semantic image similarity S9
Check-in (versions)POST/assets/{id}/checkOut → POST/assetCheckIn/{id}/validate → GET/assetCheckIn/{id} (upload URL) → PUT/assetCheckIn/{id}New-version flow S2
Uploads (11 ops)POST/uploads, PUT/PATCH /uploads/{assetId}, POST/uploads/validate, `/uploads/{id}/keywordsattributes
Metadata schema/attributes (10 ops: CRUD, data types, embedded-data types/mappings, cascading attributes), /attributeGroups (7, incl. reorder), /keywords (3), /keywordGroups (5), /metadataTemplates (6)Attribute type Status requires API ≥ 1.1 S1
Bulk metadata jobs/export/asset-metadata (6), /import/asset-metadata (6, with validation step), /update/asset-metadata (3), GET/metadata-jobs/statusPresent in APIM, not in the Postman collection; status endpoint requires CanEditMetadata or CanImportExportMetadata S9
Search helpersGET/search/facets, /mostViewed[/basic], /recentlyUploaded[/basic], /savedsearches (8 ops, incl. pinned and share)Facets: file extension only S1
Categories / folders/categories (15 ops), /folders (6), sub-categories, category assets (/basic variant), permission sets, user-group links"Folders" and "categories" are parallel routes over the same tree S2
Lightboxes (collections)/lightboxes (16 ops), approval lightboxes, policies S2
Users & groups/users (15 ops incl. /users/current, /users/current/permissions[/{resourceType}], registration fields, approvers, POST/users/password-reset-url admin-only), /groups (7)Public self-registration and password recovery under /public/… S9
Authorization (policies)GET/POST /authorization/policies, GET/authorization/resources/{resourceType}/ids; per-resource /policies on lightboxes and branded portalsPolicy-based ACLs S2
Renditions & cropsGET/config/renditionkinds, /assets/{id}/renditions, /crop (7 ops: templates, predefined templates), POST/cropWithTemplate/{assetId} S2
Direct (CDN) links/directlinks (12 ops): create per asset, list (offset/count), export, CDN report by period, activate/deactivate/archive, validateImage sizes XLarge…Thumbnail/Original/Custom; formats GIF, JPG, PDF, PNG, TIFF S2
Downloads/downloads (9 ops): download jobs, immediate download, asset URLs for download, validate S2
SharingPOST/shareAssets, POST/shareLightboxes, GET/public/share/{shareCode}/…Web galleries S2
Branded Portals/brandedportals (38 ops: CRUD, sections, sync, settings, publish, duplicate, upload sections) + /public/brandedportals/…, /public/{libraryId}/brandedportals/…Live portal reads are anonymous public routes S2
Experience portalsGET/portals/{portalId}/assets, GET/public/{libraryId}/portals/{portalId}/assets, POST/brandedportals/portals/{portalId}/non-searchable-sectionWhole-portal search for "Story / Experience" portals; not in Postman S9
External uploads/externaluploads/links (7 ops) + /public/externaluploads/{linkId}/… (7)Not in Postman S9
AI/assets/{id}/autotags, `/assets/{id}/videoIntelligence/{analyzestatus
Reports/reports (9 ops, by report type / users / groups / assets / events), /report/{reportType}, /v2/reports + /v2/reports/{id}/embed (embed token) S2
Library / org units/organizationalunits (17 ops: current org unit, libraries, portals, skin colours, logo, welcome message, Print UI credential) S2
Notifications/notification (10 ops: in-app notifications, follow asset, send) S2
Misc/quicklinks (4), /features (2, per-user feature flags), /introductionAndHelp, /public/{domainName}/termsAndConditions S9
IAM clients/iam-management/clients (5 ops: list, search, get, create, update)Present in APIM, undocumented in Postman — purpose (OAuth client management) inferred from names Unverified S9
Webhooks (SkyHOOK)GET/skyhook/events, POST/skyhook/subscriptions, GET/skyhook/subscriptions/list, PUT/DELETE /skyhook/subscriptions/{id} S10
Unify Integrations/integrations/apps (register/list/rename/delete ThirdParty apps), /integrations/allowed-origins (iframe CSP allow-list), /integrations/subscriptions…, /integrations/user-entitlement…, POST/integrations/users12 operations; envelope apiVersion/buildVersion/payload/recordCount/meta S11 S12

Rights/usage and workflow resources: no dedicated endpoints beyond asset status/approval fields, expiry dates (expiresAt), lightboxes for approval and download requests S2; proofing (PageProof) and templating (Marq) have no public API documented here (Unknown).

Data model

  • Envelope on every response: ApiVersion, Meta {MetaInformation, Warnings[], Errors[], CreatedOn}, RecordCount {TotalRecordsFound, StartingRecord, RecordsReturned}, Payload S1.
  • Asset (GUID id) with title, a media block of pre-signed URLs per rendition (thumb, small, medium, large, original, download, stream/streamingManifest) carrying sasExpiry/sasRenewal, and a file block (fileName, md5, fileType, sizeInBytes, uploadedAt, approvedAt, expiresAt, dimensions, video bitrate/frame rate, mimeType, colorMode…) S2.
  • Asset status codes used in filters: 0 approved, 2 pending, 5 rejected, 7 expired, 9 checked out S1; upload finalisation sets status 1 (ready for processing) S2.
  • Taxonomy: categories (tree, CategoryIds / CategoryAncestorIds), lightboxes, keywords (inside keyword groups, with approval status) and attributes (custom fields, grouped; data types incl. Status) S1 S2.
  • Libraries belong to an organizational unit; libraryId appears in public routes and in webhook payloads S2 S1.
  • Since v1.2 the asset DTO returns permissions as an array like other resources S1.

Search & querying

  • Full text: GET/assets?search=… (or body of POST/assets/search) across categories, keywords, file names, comments, descriptions; implicit AND, explicit AND/OR/NOT, "exact phrase", * wildcards S1.
  • Field-scoped search: field prefixes or searchFields= among categoryIds, category(ies), cognitiveBackgroundColor, cognitiveForegroundColor, cognitiveDominantColors, cognitiveTextInImage, comments, description, fileName, keywords, title; the POST body also accepts cognitiveContentInDocument, cognitiveTags, videoIntelligence S1 S2.
  • Filters: filters= with EQ NE LT GT LE GE CT SW EW, AND/OR, parentheses; case-insensitive names and values; filterable: AssetType, attribute values, AverageRating, CognitiveColor (12 colours), CreatedBy, DateApproved/CheckedOut/PendingApproval/Rejected/Uploaded, file extension, Status, CognitiveTextInImage. Filters apply before search S1.
  • Container filters: containerFilter=(CategoryIds/ANY(c: c EQ '<id>')), add CategoryAncestorIds/ANY(…) for sub-categories, LightboxIds/ANY(…) for lightboxes (OData-like lambda syntax) S1.
  • Semantic / visual: POST/assets/search accepts useSemanticSearch, semanticSearchSimilarity, useRrf (rank fusion) and fileId/fileUrl/fileSearchExactMatch (search by image) S2 — undocumented beyond the request schema Unverified.
  • Sorting: e.g. sort=record.createdAt D S2. Facets: GET/search/facets returns counts by file extension only (other facets "planned") S1.
  • include, exclude, max-length query parameters are described but marked "not implemented yet" S1.
  • Deep pagination limits / maximum count: Not public.

Uploads & binaries

Documented four/five-step flow S1 S2:

  1. POST/uploads { "filename": "…" } → holding asset record (status "Uploading") + uploadUrl, an Azure Blob SAS URL with temporary write access.
  2. PUT{uploadUrl} with the bytes (x-ms-blob-type header) directly to Azure Blob Storage.
  3. PUT/uploads/{assetId} with filename, title, description, fileSizeInBytes (required to be the original size).
  4. POST/uploads/{assetId}/categories (assign at least one category; keywords, attributes, lightboxes have sibling endpoints).
  5. PATCH/uploads/{assetId} JSON Patch [{"op":"replace","path":"/status","value":1}] → pre-flight validation, rename handling, processing (thumbnails, AI).
  • Single PUTs are limited to roughly 64 MB; larger files must be sent in blocks with the Azure Storage SDKs (C# sample provided) S1 S16.
  • New versions: check-out / check-in flow (see Core resources) with priority=high on the final PUT in the guide S2.
  • Downloads: rendition URLs in the asset media block are SAS-signed and expire (sasExpiry) S2; download jobs via /downloads; persistent public URLs via direct links (POST/directlinks/{assetId} with RenditionSettings size/format and LinkSettings incl. IsUniqueLink, IsEmbedCode) S2. UI-side CDN transformations (AVIF/WebP auto-format, resize ≤ 2,000 px) are documented for the UI S65; their URL syntax is Not public.

Events & webhooks

  • Service: SkyHOOK, https://api.mediavalet.com/skyhook, separate APIM API with its own subscription requirement S8 S10.
  • Events (8): Asset.StatusUpdated, Asset.MediaFileAdded, Category.AssetsAssigned, Category.AssetUnassigned, Asset.KeywordsAdded, Asset.AttributesAdded, Asset.VideoRenditionsAdded, Asset.KeywordRemoved S1 S25. Asset.StatusUpdated fires on statuses such as Activated, PendingApproval(WithAnnotations), Approved, Rejected, Expired, Deleted, SoftDeleted, CheckedOut S28. No user, portal, CDN-link or deletion-specific events.
  • Configuration: by API only — POST/skyhook/subscriptions with Events[], Type = webhook (Data.webhook URL) or eventgrid (Data.eventGridTopicEndpointUrl + eventGridKey); PUT to change events; one subscription per webhook URL (a second one with the same URL fails with 400 "subscription found with similar data") S1 S27.
  • Validation: CloudEvents 1.0 webhook abuse-protection handshake — an HTTP OPTIONS request; answer synchronously with WebHook-Allowed-Origin (and WebHook-Allowed-Rate) headers or asynchronously by calling WebHook-Request-Callback; failure leaves the subscription in status Failed S1 S26.
  • Payload: CloudEvents JSON (id, source, type, time, specversion: "1.0", subject like /library/{libraryId}/assets/{assetId}/Asset.StatusUpdated, data with LibraryId, AssetId and event specifics; Asset.MediaFileAdded carries a MediaFileBlobUrl) S1.
  • Signature / retries: no payload signature or retry policy documented (Unknown).

Limits & quirks

  • Two credentials on every call (bearer token + APIM subscription key) — the most common onboarding pitfall; the subscription key is tied to the developer-portal plan, OAuth clients are issued manually by Support S1 S21 S15.
  • Manual onboarding: no self-service client creation; redirect URIs are whitelisted by Support S22.
  • Admin-centric: the developer portal says an administrator account is needed to use the API S5.
  • Documentation drift: 64 APIM operations (metadata import/export/update jobs, metadata templates, external uploads, quick links, IAM clients, experience-portal search, duplicate search…) are absent from the Postman collection S2 S9; the docs changelog stops at v1.2 (2025-06-13) S1; the developer-portal "API changelog" page is not readable without JavaScript.
  • Changelog dates use US MM/DD/YYYY format in the docs (e.g. "03/06/2024" = 2024-03-06) Unverified interpretation based on ordering.
  • 401 vs 403: from v1.2, missing permission → 403; on v1.0/1.1 it remains 401 S1.
  • Facets limited to file extensions; include/exclude/max-length not implemented S1.
  • Gateway: api.mediavalet.com is fronted by Cloudflare and Azure APIM S15; the APIM backend reported for the NextGen API is a regional host (api-usca.mediavalet.net) S12 — whether other regions use other backends is Not public.
  • Upload size: ~64 MB per single blob PUT; Azure block upload beyond S1.
  • Duplicate detection at upload (UI) does not apply to API uploads S30.
  • Rate-limit headers / 429 behaviour: Not public.

SDKs, tools & code samples

ToolLanguage / formMaintainerStatus
MediaValet/how-to-samples — large-file uploadC# (.NET 8)MediaValetLast push 2025-02-03; uses password grant S16
MediaValet/Mediavalet.AzureMediaMigrationC#MediaValet (fork of a Microsoft sample)Azure Media Services migration tool, last push 2024-06-13 S17
Postman collection + "Guide Variables" environmentPostmanMediaValetRun-in-Postman from docs.mediavalet.com S1 S3
Asset Picker (Unify PBC)iframe + postMessage (insertedAssets event; params allowedAssetTypes, allowedFeatures, redirectType)MediaValetEnabled per domain by Support or self-serve whitelisting; local dev on http://localhost:5174 S1 S78
PowerShell—MediaValetMentioned on the developer portal home page; no public module found Unverified S4

No official SDK packages on npm, NuGet, PyPI or Packagist S18. Community libraries: none found.

Changelog of the API

DateChange
2025-06-13v1.2: asset DTO permissions consolidated into an array; 401 → 403 for authenticated-but-unauthorized calls S1
2024-05-22v1.1: stream / streamLoDef deprecated (Azure Media Services retirement); streamingManifest, fullStreamAvailable added S1
2024-03-06v1.1: attribute type Status in /attributes endpoints and PATCH/assets/{id}; sending Status attributes on older versions → 400 S1
2023-08-30Postman documentation (re)published at docs.mediavalet.com S3
Unknownv1.0 initial release S1

Stored API specs

11 files · 2.6 MB · verbatim copies of public vendor filesSpecs README & provenance
FileFormatSizeDownload
mediavalet_apim_nextgen-api_openapi-export.yamlOpenAPI411 BDownload
mediavalet_apim_nextgen-api_operations_p1.jsonJSON22 KBDownload
mediavalet_apim_nextgen-api_operations_p2.jsonJSON22 KBDownload
mediavalet_apim_nextgen-api_operations_p3.jsonJSON23 KBDownload
mediavalet_apim_nextgen-api_operations_p4.jsonJSON14 KBDownload
mediavalet_apim_skyhook-api_openapi-export.yamlOpenAPI405 BDownload
mediavalet_apim_skyhook-api_operations_p1.jsonJSON675 BDownload
mediavalet_apim_unify-integrations_openapi-export.yamlOpenAPI1.2 KBDownload
mediavalet_apim_unify-integrations_operations_p1.jsonJSON4.3 KBDownload
mediavalet_postman_collection.jsonPostman collection2.5 MBDownload
mediavalet_postman_documenter_metadata.jsonPostman collection9.4 KBDownload
Search the wiki