This page contains examples for specific actions using the REST API.
The Accurate Video API is a REST API that is accessed through the HTTP protocol, and credentials must be provided when authentication is enabled.
Accurate Video supports the following authentication schemes. Note that they can all be used simultaneously.
Regular HTTP Basic Auth with username and password
curl -H 'Accept: application/json' 'https://server-address/whoami' -u 'username:password' | python -m json.tool | less
Note that basic auth can not be used to authenticate users that are managed externally, e.g. users managed by Keycloak, Active Directory, or AWS Cognito.
Bearer auth using JWT.
curl -H 'Accept: application/json' 'https://server-address/api/whoami' -H 'Authorization: Bearer {access token}' | python -m json.tool | less
How to obtain a bearer token varies depending on how users and identities are managed. If Keycloak is used the following command can be used to obtain a bearer token.
curl -s -X POST 'https://keycloak-server/auth/realms/{realm name}/protocol/openid-connect/token' \ --data-urlencode 'client_id={client id}' \ --data-urlencode 'grant_type=password' \ --data-urlencode 'username={username}' \ --data-urlencode 'password={password}' | python -c 'import json,sys; print(json.load(sys.stdin)["access_token"]);'
Where realm name and client ID can be found in the Keycloak admin console.
These fields are updated by the system and should not be modified.
health_status
error_message
files_total
files_ingested
space_used
space_free
refresh_timestamp
These fields may be modified by an application.
name
access:read
access:write
access:delete
access:list
public_read
public_url
tag
lowres
marker_export
original
poster
poster_overlay
sprite_map
rekognition
refresh_interval
Examples: "PT20.345S" -- parses as "20.345 seconds" "PT15M" -- parses as "15 minutes" (where a minute is 60 seconds) "PT10H" -- parses as "10 hours" (where an hour is 3600 seconds) "P2D" -- parses as "2 days" (where a day is 24 hours or 86400 seconds) "P2DT3H4M" -- parses as "2 days, 3 hours and 4 minutes"
auto_ingest:*
Fields specific for AWS_S3 and AWS_GLACIER type storages *
aws:region
aws:profile
aws:access_key_id
aws:secret_access_key
To use server credentials - set `aws:access_key_id` and `aws:secret_access_key` to `null`. - set `public_read` to false.
Fields specific for AWS_S3 type storages *
aws:sse_algorithm
aws:kms_cmk_id
Fields specific for AZURE_BLOB type storages *
azure:account_name
azure:account_key
POST /storage { "type": "AWS_S3", "uri": "s3://accurate-video-bucket" "metadata": [ { "key": "name", "value": "Test storage" }, { "key": "refresh_interval", "value": "PT15M" }, { "key": "tag", "value": "original" }, { "key": "tag", "value": "rekognition" }, { "key": "aws:region", "value": "eu-central-1" }, { "key": "access:public_read", "value": "false" } ] }
See Writable storage metadata fields for all available metadata options.
POST /storage { "type": "AZURE_BLOB", "uri": "blob://accurate-video-container" "metadata": [ { "key": "name", "value": "Test storage" }, { "key": "refresh_interval", "value": "PT15M" }, { "key": "tag", "value": "original" }, { "key": "azure:account_name", "value": "account-name" }, { "key": "azure:account_key", "value": "account-key" } ] }
See Writable storage metadata fields for all available metadata options.
For a local storage, you need to provide a local uri and a public url to a mount point.
POST /storage { "type": "LOCAL", "uri": "/absolute/mount/point" "metadata": [ { "key": "name", "value": "Test storage" }, { "key": "refresh_interval", "value": "PT15M" }, { "key": "tag", "value": "original" }, { "key": "public_url", "value": "https://www.example.com/storage" } ] }
See Writable storage metadata fields for all available metadata options.
A source storage should be read-only, containing nothing but original files. This should first of all be enforced at its source, e.g. setting the actual S3 bucket as read-only.
Protect the storage by setting metadata tag
access:write
false
PUT /storage/{storageId}/metadata [ { "key": "access:write", "value": "false" } ]
This will prevent AV from writing lowres proxies, spritemaps, posters etc to the storage.
A destination storage should allow these actions by setting
access:write
true
PUT /storage/{storageId}/metadata [ { "key": "access:write", "value": "true" }, { "key": "tag", "value": "lowres" }, { "key": "tag", "value": "marker_export" }, { "key": "tag", "value": "poster" }, { "key": "tag", "value": "poster_overlay" }, { "key": "tag", "value": "sprite_map" } ]
See Writable storage metadata fields for all available options.
Automatic ingest is configured by a specific set of storage metadata. See Auto Ingest for details and explanations.
The following example updates an existing storage but can of course be applied on storage creation as well.
PUT /storage/{storageId}/metadata [ { "key": "auto_ingest:enabled", "value": "true" }, { "key": "auto_ingest:include", "value": "incoming/*" }, { "key": "auto_ingest:manifest:enabled", "value": "true" }, { "key": "auto_ingest:manifest:include", "value": "manifest/*.json" } ]
This enables auto ingest for all files uploaded to the
incoming/
JSON
manifest/
Files can be located using wildcard serches on file name.
GET /storage/{storage id}/file?search=*.mp4
Output:
{ "values": [ { "fileLocations": [ { "fileName": "1463dfc3-ec9a-497e-b11a-d08c55d354ab/7015f72f-4cd5-4a6c-8edc-bd78ef2d4050_Video.mp4", "fileSize": 29895620, "uri": "s3://accurate-player/1463dfc3-ec9a-497e-b11a-d08c55d354ab/7015f72f-4cd5-4a6c-8edc-bd78ef2d4050_Video.mp4" } ], "id": "101" }, { "fileLocations": [ { "fileName": "1463dfc3-ec9a-497e-b11a-d08c55d354ab/f0e446ec-534b-4b81-8457-35c9a2e64d91_Audio.mp4", "fileSize": 1763417, "uri": "s3://accurate-player/1463dfc3-ec9a-497e-b11a-d08c55d354ab/f0e446ec-534b-4b81-8457-35c9a2e64d91_Audio.mp4" } ], "id": "204" } ] }
This will return all timespan markers for the asset.
GET /asset/{assetId}/timespan
All timespan markers have a type. This request will return all timespan objects having type "Baton" or "Manual".
GET /asset/{assetId}/timespan?type=Baton&type=Manual
POST /api/asset/{assetId}/metadata/group [ { "type": "Manual", "metadata": [ { "key": "name", "value": "Test" } ] } ]
Output:
{ "creationDate": null, "updateDate": null, "version": null, "id": "123892", "type": "Manual", "metadata": [ { "creationDate": "2021-03-26T13:50:45.724680577Z", "updateDate": "2021-03-26T13:50:45.724680577Z", "version": 0, "id": "123902", "key": "name", "value": "Test2" } ], "blob": null }
POST /api/asset/{assetId}/timespan [ { "start": { "frame": 3826, "numerator": 24, "denominator": 1 }, "end": { "frame": 3827, "numerator": 24, "denominator": 1 }, "type": "Manual", "metadata": [ { "key": "name", "value": "test" }, { "key": "description" }, { "key": "subtype", "value": "123892" } ] } ]
Assets can be created without executing a job.
First locate the files that should be added to the asset, e.g. using search filter
Then, create the asset.
POST /asset?skip_ingest=true { "metadata": [ { "key": "title", "value": "My awesome asset" } ], "files": [ { "id": "101", "type": "VIDEO", "metadata": [ { "key": "tag", "value": "mp4_lowres" } ] }, { "id": "204", "type": "AUDIO", "metadata": [ { "key": "tag", "value": "aac_surround_5.1" }, { "key": "language", "value": "en_US" } ] } ] }
Output. Note that the asset will contain no sprite maps, and the files will have no media information like frame rate.
{ "creationDate": "2020-11-27T13:23:50.782712Z", "files": [ { "assetId": "5655", "creationDate": "2020-11-27T13:05:03.902Z", "fileLocations": [ { "fileId": "101", "fileName": "1463dfc3-ec9a-497e-b11a-d08c55d354ab/7015f72f-4cd5-4a6c-8edc-bd78ef2d4050_Video.mp4", "fileSize": 29895620, "uri": "s3://accurate-player/1463dfc3-ec9a-497e-b11a-d08c55d354ab/7015f72f-4cd5-4a6c-8edc-bd78ef2d4050_Video.mp4", "url": "https://accurate-player.s3.eu-central-1.amazonaws.com/1463dfc3-ec9a-497e-b11a-d08c55d354ab/7015f72f-4cd5-4a6c-8edc-bd78ef2d4050_Video.mp4" } ], "fileName": "1463dfc3-ec9a-497e-b11a-d08c55d354ab/7015f72f-4cd5-4a6c-8edc-bd78ef2d4050_Video.mp4", "id": "101", "metadata": [ { "creationDate": "2020-11-27T13:05:03.903Z", "id": "111", "key": "aws:etag", "updateDate": "2020-11-27T13:05:03.903Z", "value": "d467becb0c0874333f541b83450d9ebc-3" }, { "creationDate": "2020-11-27T13:23:50.785211Z", "id": "5516", "key": "tag", "updateDate": "2020-11-27T13:23:50.785211Z", "value": "mp4_lowres" } ], "storageId": "21", "type": "VIDEO", "updateDate": "2020-11-27T13:23:50.791846Z", "uri": "s3://accurate-player/1463dfc3-ec9a-497e-b11a-d08c55d354ab/7015f72f-4cd5-4a6c-8edc-bd78ef2d4050_Video.mp4", "url": "https://accurate-player.s3.eu-central-1.amazonaws.com/1463dfc3-ec9a-497e-b11a-d08c55d354ab/7015f72f-4cd5-4a6c-8edc-bd78ef2d4050_Video.mp4" }, { "assetId": "5655", "creationDate": "2020-11-27T13:05:03.902Z", "fileLocations": [ { "fileId": "204", "fileName": "1463dfc3-ec9a-497e-b11a-d08c55d354ab/f0e446ec-534b-4b81-8457-35c9a2e64d91_Audio.mp4", "fileSize": 1763417, "uri": "s3://accurate-player/1463dfc3-ec9a-497e-b11a-d08c55d354ab/f0e446ec-534b-4b81-8457-35c9a2e64d91_Audio.mp4", "url": "https://accurate-player.s3.eu-central-1.amazonaws.com/1463dfc3-ec9a-497e-b11a-d08c55d354ab/f0e446ec-534b-4b81-8457-35c9a2e64d91_Audio.mp4" } ], "fileName": "1463dfc3-ec9a-497e-b11a-d08c55d354ab/f0e446ec-534b-4b81-8457-35c9a2e64d91_Audio.mp4", "id": "101", "metadata": [ { "creationDate": "2020-11-27T13:05:03.903Z", "id": "111", "key": "aws:etag", "updateDate": "2020-11-27T13:05:03.903Z", "value": "d41d8cd98f00b204e9800998ecf8427e-2" }, { "creationDate": "2020-11-27T13:23:50.785211Z", "id": "5516", "key": "tag", "updateDate": "2020-11-27T13:23:50.785211Z", "value": "aac_surround_5.1" }, { "creationDate": "2020-11-27T13:23:50.785211Z", "id": "5517", "key": "language", "updateDate": "2020-11-27T13:23:50.785211Z", "value": "en_US" } ], "storageId": "21", "type": "AUDIO", "updateDate": "2020-11-27T13:23:50.791846Z", "uri": "s3://accurate-player/1463dfc3-ec9a-497e-b11a-d08c55d354ab/f0e446ec-534b-4b81-8457-35c9a2e64d91_Audio.mp4", "url": "https://accurate-player.s3.eu-central-1.amazonaws.com/1463dfc3-ec9a-497e-b11a-d08c55d354ab/f0e446ec-534b-4b81-8457-35c9a2e64d91_Audio.mp4" } ], "id": "5655", "metadata": [ { "creationDate": "2020-11-27T13:23:50.782793Z", "id": "5668", "key": "title", "updateDate": "2020-11-27T13:23:50.782793Z", "value": "My awesome asset" } ], "updateDate": "2020-11-27T13:23:50.791816Z" }
A collection is simply an asset with a collection flag.
POST /asset { "collection" : true, "metadata" : [ { "key" : "title", "value" : "My new collection" } ] }
It is possible to ingest a file into an existing collection but you can also do it manually by creating a relation.
POST /asset/{parentId}/relation/{childId}
where
parentId
childId
Several assets/collections can be moved in one bulk operation.
POST /asset/relation/bulk { "assetRelationUpdates": [ { "childId": "2665854", "currentParentId": "2096052", "mode": "Move" }, { "childId": "2524264", "currentParentId": null, "mode": "Move" } ], "parentId": "2485276" }
childId
currentParentId
null
parentId
Several files of different types can be ingested together and combine a new asset using the endpoint
POST /asset
This action starts an ingest job in the background, and will return the job id. The ingest job will - extract media info, storing it as file metadata - perform heavy operations like transcoding (creating proxy files) and creating sprite maps.
To get information about the progress of the job, use the endpoint
GET /job/{job-id}
First locate the files that should be added to the asset, e.g. using search filter
POST /asset { "files" : [ { "id" : "112", "type" : "AUTO" } ], "metadata" : [ { "key" : "title", "value" : "My new asset" } ] }
The type for the file can be one of: - AUTO - VIDEO - AUDIO - SUBTITLE - BATON - STILL_FRAME - MANIFEST - MARKER
The system will make it's best effort to try to guess the type if AUTO is given.
A file can be mapped to an existing collection.
First locate the files that should be added to the asset, e.g. using search filter
POST /asset { "files" : [ { "id" : "112", "type" : "AUTO" } ], "metadata" : [ { "key" : "title", "value" : "My new asset" } ], "parentId" : 22401 }
This will ingest the file into an asset that is mapped to the collection with id
22401
First locate the files that should be added to the asset, e.g. using search filter
POST /asset { "files" : [ { "id" : "98", "metadata" : [ { "key" : "tag", "value" : "lowres" } ], "type" : "VIDEO" }, { "id" : "1031", "metadata" : [ { "key" : "tag", "value": "mp4-6track" } ], "type" : "AUDIO" }, { "id" : "742", "metadata" : [ { "key" : "language", "value" : "ger" } ], "type" : "SUBTITLE" } ], "metadata" : [ { "key" : "title", "value" : "My new asset" } ] }
If you ingest files already in a format supported by browsers, there is no need to transcode new proxies.
First locate the files that should be added to the asset, e.g. using search filter
Then, create the asset.
POST /asset?skip_transcode=true { "metadata": [ { "key": "title", "value": "My awesome asset" } ], "files": [ { "id": "101", "type": "VIDEO", "metadata": [ { "key": "tag", "value": "mp4_lowres" } ] }, { "id": "204", "type": "AUDIO", "metadata": [ { "key": "tag", "value": "aac_surround_5.1" }, { "key": "language", "value": "en_US" } ] } ] }
The ingest job will perform all the operations explained here but it will skip the transcode job, significatly increating the speed of the ingest.
First locate the files that should be added to the asset, e.g. using search filter
POST /asset/ingest { "assetId": "16881", "fileIds": ["1234", "2345"] }
This can also be used to run ingest actions for a set of files attached to an existing asset, that was created without running ingest. File ids given that are attached to the given asset already will have ingest actions performed on them. File ids that are not attached to any asset as of yet, will be attached to the given asset, and then ingest actions will be run on them. An optional query parameter can be provided,
all_files=true
Access can be defined on asset creation.
First locate the files that should be added to the asset, e.g. using search filter
POST /asset { "files": [ { "id": "112", "type": "AUTO" } ], "metadata": [ { "key": "title", "value": "Asset with access preconfigured" } ], "access": [ { "entries": [ { "accessTypes": ["read"], "filters": [] } ], "principals": [ { "identifier": "restricted-user", "principalType": "USER" } ] }, { "entries": [ { "accessTypes": ["read", "modify_all_access", "write"], "filters": [] } ], "principals": [ { "identifier": "admin-user", "principalType": "USER" } ] } ] }
For more information and examples, see Access Documentation
Access can be updated for an existing asset.
NOTE This will replace the current access configuration entirely.
POST /asset/{assetId}/access [ { "entries": [ { "accessTypes": ["read"], "filters": [] } ], "principals": [ { "identifier": "restricted-user", "principalType": "USER" } ] }, { "entries": [ { "accessTypes": ["read", "modify_all_access", "write"], "filters": [] } ], "principals": [ { "identifier": "admin-user", "principalType": "USER" } ] } ]
For more information and examples, see Access Documentation