This is a REST API to the Approval Studio, a review and packaging SAAS.
API utilizes its flow, authorization , storage and so on.
Approval Studio basic concepts
From business point of view, Approval Studio is based on a multitenant concept when a single user may by a part of one or more tenants (called Companies). Please see https://approvalstudio.freshdesk.com/ for detailed instructions on how to work with Approval Studio.
Currently the only point where you may choose a tenant is project creation, please see POST /api/v1/project / Request.
REST HTTP Codes
API may return one of the following HTTP codes:
HTTP Code
Response
200
Success. See method description to get what and how method returns.
400
Validation error. API validates input parameters and when finds invalid parameter, throws HTTP code 400. Those errors are related to parameters’ presence, format, emptiness etc. Validating against database, like looking for data by a ID is conducted separately and reflected in case of error, in HTTP codes 404, 406, 412 etc., please see methods description for detailed explanations.
{
"errors": {
"parameterName": [
"'parameterName' must not be empty."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|a4a45224-4a7c03bbd5172369."
}
HTTP Code
Response
404, 406, 412
Resource not found. Generally it means that requested resources either not found and somehow restricted to proceed. For example, a given project id is non-existent, the project not found so gets HTTP code 404.
429
Rate Limit Reached. API host calculates number of calls per sec, minute and hour, and when rate of requests reaches limit, throws HTTP code 429 that means that the API host is overloaded and client needs to wait before retrying.
If the request gets blocked then the client receives a text response like this:
Status Code: 429
Retry-After: 58
Content: API calls quota exceeded! maximum admitted 2 per 1m.
Retry-After header value is expressed in seconds. And X-Rate-Limit-XXX HTTP headers are injected in the response:
X-Rate-Limit-Limit: the rate limit period (eg. 1m, 12h, 1d)
X-Rate-Limit-Remaining: number of request remaining
X-Rate-Limit-Reset: UTC date time (ISO 8601) when the limits resets
HTTP Code
Response
500
Infrastructure failure. This means critical unrecoverable technical error generally related to database connections, external services availability, hardware failure etc. Depends on the client application flow you can retry calling method or halt processing and call our technical support.
Authorization/authentication
The API is based on authorization token which should be requested prior to using any available API methods.
The flow is following: request auth token by calling POST/api/v1/token/login (see) providing Approval Studio’s username/password. If ok, the method returns an authorization token that you should provide with any other API call as a HTTP header like this: Authorization: Bearer XXXXXXXXXXX.
The token is valid for a limited amount of time, 120 minutes by default. When expired and still used you will have response HTTP code 401, Unauthorized :
If so, you need to obtain a new token.
If token is invalid or not provided, it gets the same response HTTP code 401.
Token management
POST/api/v1/token/login
Authorizes a user. When successfully authorized returns an authorization token which must be supplied to every API as a header, like "Authorization: Bearer YYYYYYYYYYYYYYYYY...".
Business project or product name this Approval Studio project related for, max-length 50 chars, optional.
design
Point to which type of design this is, max-length 50 chars, optional.
revision
Ideally, a sequential number or version number; generally a free form string max-length 50 chars, optional.
description
Any kind of additional information, descriptions, comment etc., max-length 200 chars, optional.
tags
Array of free-form single-word tags associated with project, optional, max 20 elements of 20-chars tags.
dueDate
Optional date, UTC, that points when the project is desired to be completed.
reviewStatus
r/o
pendingCount - count of non-completed review tasks assigned on the project
approvedCount - count of approves made on the project’s assets
rejectedCount - count of rejected made on the project’s assets
created
r/o
Refers when the project was created, UTC.
Method/Path
Description
GET /api/v1/project
Getting list of projects.
POST /api/v1/project
Create new project.
PUT /api/v1/project
Edit existing project.
DELETE /api/v1/project
Delete a project.
GET /api/v1/project/proofreport
Get a link to a proof report for a project.
PUT /api/v1/project/state
Change project’s state.
GET /api/v1/project
Returns one or more projects and projects’ assets, tasks, reference documents – depends on the parameters passed.
All the parameters are optional; method always uses AND combination of all the parameters.
Parameter
Type & Explanation
ProjectUID
string Unique project GUID. If provided, only one project will retrieved.
States
string One or more project states, comma-separated, see ProjectStates above. Default value is Active,OnHold,Completed.
Query
string A free-form text to case-sensitive search in projects’ attributes: Project name, Customer, Project, Design, Revision, Description, Tags.
IsLoadAssets
boolean, false by default. if set, returns assets for every project as a child collection.
IsLoadLastVerAssets
boolean, true by default. If set, only the most recent version of every asset be returned. Ignored, if IsLoadAssets is not set.
IsLoadTasks
boolean, false by default. Is set, list of active tasks for every project would be returned as a child collection.
IsLoadRefDocs
boolean, false by default. Is set, list of uploaded reference documents for every project would be returned as a child collection.
string array Optional tag list, max 20 tags of max length of 25 chars each.
dueDate
ISO date Optional UTC date (or date-time) that point to a date when project supposed to be completed. The date affects project’s status and sort order on the application dashboard.
projectOwnersUIDS
string array Mandatory list of the project owner(s)'s UIDs. At least one owner must be provided, max number of owners is 20.
{
"clientUID": "string", // Optional tenant(client) ID.
"projectName": "string", // Project name, mandatory.
"customer": "string",
"project": "string",
"design": "string",
"revision": "string",
"description": "string",
"tags": [
"string", "string"
],
"dueDate": "2020-12-07T20:56:38.818Z",
"projectOwnersUIDS": [ // Project owner(s), at least one owner must be provided.
"XXXXXXXX"
]
}
Error: Project with the given ID not found or it has been already deleted.
{
"version": "1.0",
"statusCode": 404,
"message": "Project not found or already deleted."
}
HTTP Code
Response
406
Error: Project’s editing is possible only when the project is Active or OnHold. Completed, Archived or InTransit projects are not mutable. Please see PUT /api/v1/project/state.
Error: Project with the given ID not found and therefore project deteion failed.
{
"version": "1.0",
"statusCode": 404,
"message": "Project not found."
}
HTTP Code
Response
412
Error: Project must be either Completed or Archived to be deleted.
GET /api/v1/project/proofreport
Returns URL to get a printable proof report for the given project. The method does not allow direct downloading.
Read result/downloadURL and navigate it to get the report body. The report is a plain single-layer PDF 1.4 file.
Request
Request is a set of URL GET parameters separated by &:
Error: Project with the given ID not found and therefore proof report generation failed.
{
"version": "1.0",
"statusCode": 404,
"message": "Project not found."
}
PUT /api/v1/project/state
Changes project’s state according state rules:
The diagram above explains pre-requisite check for changing project’s state. Note: Detailed description of the project management is out of scope of this document.
States
Those are the states:
State
Explanation
Active
Work on a project is undergo. This is where all the review work is going on.
OnHold
Due some reason you want to postpone working on a project. Setting state to OnHold moves the project to a separate lane. Tasks are still intact, the only difference from Active is a position on a separate lane on the dashboard.
Completed
When setting state to Completed all projects task are deleted and the project itself moves from dashboard to a separate screen where all completes stored separately. All the assets, reference documents are preserved as well as history etc. The project goes read-only.
Archived
This is generally the same as Completed but assets and reference documents moved to a remote, slow storage. Process of moving files to other storage could take a while, so when it is going on, the system marks a project as InTransit (see below).
InTransit
Project is locked to InTransit state by API itself when it is switching to Archive state or, vice versa, from Archived to Active. You can’t set this state forcedly.
Error: Project with the given ID not found or it has been already deleted.
{
"version": "1.0",
"statusCode": 404,
"message": "Project not found."
}
HTTP Code
Response
406
Error: Project with the given ID is already have requested state; no updating made.
{
"version": "1.0",
"statusCode": 412,
"message": "Project already has state XXXX."
}
HTTP Code
Response
412
Error:Please see the diagram above.
You cannot change state arbitrarily, for instance you can not change from Active to Archived. To move project to archive, you need to make it Complete first, which forces project cleaning, and then change the state to Archive.
{
"version": "1.0",
"statusCode": 412,
"message": "You cannot directly change state from {XXXX} to {YYYY}. Please refer documentation."
}
Asset management
Method/Path
Description
GET /api/v1/assets
Gets an asset instance.
DELETE /api/v1/assets
Deletes an asset.
POST /api/v1/assets/upload
Uploads an asset.
GET /api/v1/assets/download
Downloads an asset.
GET /api/v1/assets/proofreport
Get a link to a proof report for an asset.
GET /api/v1/asset
Gets an asset instance by a given asset id.
Parameter
Type & Explanation
AssetUID
string Unique asset GUID.
Curl:
curl -X GET "http://api.approval.studio/api/v1/asset?AssetUID=XXXXXXX" -H "accept: text/plain"
Responses
HTTP Code
Response
200
Success. Asset instance returned.
"version": "1.0",
"statusCode": 200,
"message": "GET Request successful.",
"result": {
"assetUID": "xxxxxxxxxx",
"version": 1,
"name": "drawing.pdf",
"status": "Processed",
"reviewStatus": { // Proof review status (see proofing flow explanations).
"pendingCount": 1, // The asset has 1 uncompleted review task
"approvedCount": 2, // The asset has been approved 2 times
"rejectedCount": 3 // The asset has been rejected 3 times
},
"pagesCount": 3,
"created": "2020-10-22T08:09:05.778512",
"fileSize": 1063800,
"reviewUrl": "https://app.approval.studio/xxx", // URL to launch prooftool for view this asset.
"thumbnailUrl": "https://app.approval.studio/yyy" // URL to asset's thumnail image (.jpg).
}
}
HTTP Code
Response
400
Error: Parameters’ validation failed.
See HTTP code 400 description.
HTTP Code
Response
404
Error: Asset with the given ID not found.
{
"version": "1.0",
"statusCode": 404,
"message": "Asset not found."
}
DELETE /api/v1/asset
Deletes an asset by a given asset id.
Asset deletion is unrecoverable operation that leads to removing the asset from project and deleting a file from storage.
It is no way to restore asset after it’s deleted.
{
"version": "1.0",
"statusCode": 404,
"message": "Asset not found."
}
POST /api/v1/asset/upload
Uploads an asset and initiates asset processing.
It validates initial input and adds the asset to asset processing queue, which runs asynchronously. After uploading you need to pool asset status to get know when it is processed or failed to process.
Time required to process assets is highly dependent on asset file size and dimensions and on how much processing node(s) are loaded.
Asset processing may fail or be rejected due number of reasons, business and technical. Those could be asset type (file extension), resolution or physical size (in case of vector images - PDF/AI etc), payment plan and number of other options. Please refer company’s site or/and support to learn more.
Request
Parameter
Type & Explanation
ProjectUID
string Unique project ID, mandatory.
File
form file Asset file to upload and process, mandatory.
Success. "Asset uploaded successfully and is pending to process.
{
"version": "1.0",
"statusCode": 200,
"message": "Asset uploaded successfully and is pending to process.
Track it's status to catch when it'd ready to use.",
"result": {
"assetUID": "AAAAAAAAAAAAAAAAA" // newly generated asset id.
}
}
Error: You can not create a task for a project in state Complete. Only projects that are Active or OnHold can have tasks.
412
Error: User with UID [ZZZZZZZZZZZZZ] not found.
{
"version": "1.0",
"statusCode": 412,
"message": "You can not create a task for a project in state [Complete]."
}
POST /api/v1/task/review_asset
Creates a new Review Asset Task for a given user, project and list of assets providing optional due date and comment.
Request
{
"projectUID": "XXXXXXXXXXXXXX", // Project this task belongs to, mandatory.
"userUID": "ZZZZZZZZZZZZZ", // User this task assign to, mandatory.
"assetUIDs": [
"AAAAAAAAAAAAAAAA1", // One or more assets to review, namdatory.
"AAAAAAAAAAAAAAAA2"
],
"dueDate": "2020-12-04", // Task due date, UTC, optional.
"comment": "comment text" // Comment text, optional.
}
Error: You can not create a task for a project in state [Complete]. Only projects that are Active or OnHold can have tasks.
412
Error: User with UID [ZZZZZZZZZZZZZ] not found.
{
"version": "1.0",
"statusCode": 412,
"message": "You can not create a task for a project in state [Complete]."
}
POST /api/v1/task/review_asset_ext
Creates a new External Review Asset Task for someone who doesn’t have account in Approval Studio.
The flow is the following:
When task is created, a email is sent to an email address from the request.
Email contains a link (URL) to a proof report review session.
Approve or reject terminates the review task and made the URL expired.
Request
{
"projectUID": "XXXXXXXXXXXXXX", // Project this task belongs to, mandatory.
"email": "string", // User's email, mandatory.
"assetUIDs": [
"AAAAAAAAAAAAAAAA1", // One or more assets to review, namdatory.
"AAAAAAAAAAAAAAAA2"
],
"dueDate": "2020-12-04", // Task due date, UTC, optional.
"password": "string", // Optional password. When provided, is asked to provide
// before review session.
"emailSubject": "string", // Custome email subject line; override template's one. Optional.
"emailLanguage": "English", // Email language, optional. English is default.
// English, German, French, Polish, Spanish, Hebrew, Ukrainian.
"comment": "comment text" // Comment text, optional.
"isAllowDownloadAssets": true, // When true, allows user to download original file.
"isReadOnly": true // When true, make a review session read-only: no annotations,
// no comments, no approve/reject. Optional.
}
{
"version": "1.0",
"statusCode": 404,
"message": "Annotation not found."
}
HTTP Code
Response
412
Error: It’s only that user that created annotation or comment can delete it. You can not delete other’s users’ annotation and this annotation does not belong to you. Deletion failed.
{
"version": "1.0",
"statusCode": 404,
"message": "You can delete only your annotation."
}
Approval Studio API uses webhooks to notify your application when an event happens. Webhooks are particularly useful for asynchronous events like when asset accepted or rejected or when a new task created or someone made a comment or a new asset version uploaded etc.
Begin using the webhooks in three steps:
Create a webhook endpoint on your server.
Register the endpoint with Webhook management method POST /api/v1/webhook.
Test it to be sure that you can receive events using method PUT /api/v1/webhook/test.
Webhooks generally refers to a combination of elements that collectively create a notification and reaction system within a larger integration.
The webhook endpoint is code on your server, which could be written in C#, Java, Ruby, PHP, Node.js, or any other language/technology you prefer. The webhook endpoint has an associated URL (e.g., https://example.com/webhook). Note: Explanations how to build a endpoint is out of scope of this document.
The Approval Studio notifications are Event objects. This Event object contains all the relevant information about what just happened, including the type of event and the data associated with that event. The webhook endpoint uses the event details to take any required actions.
Security
The API host provides a Secret ID with every event object posted on an endpoint. Endpoint needs to check against this ID for every incoming post to avoid spamming. Keep secret id safe.
Retry logic
Webhook host implements a simple retry logic in order to try to deliver events in case of possible troubles on endpoint side
If endpoint does not return HTTP code 200, the webhooks host starts retrying posting the same event object up to ~30 minutes. After that time the event delivery silently fails.
Event object
Event object is a JSON document that API posts on a selected endpoint. It, generally has the following structure:
{
"EventId":"DY3h1Pl040uIRvL74oKFlQ", // Unique event id.
"EventType":"annotation.added", // Codename of the event, see below.
"Created":"2021-02-18T14:08:08.615088Z", // UTC datetime when the event was generated.
"Data": { // Data block, event-type dependent.
"SomeData": "XXXXXXXX"
}
}
EventID is unique for every Event object. If, for whatever reason, API host make more than one post on your endproint with the same event object, you can it by reading EventID. Event codes are self-explanatory:
Event code
Description
project.created
Fires when a new project created.
project.edited
Fires when a project’s attribute changed, like name, description, due date etc.
project.state
Fires when project state changes.
asset.uploaded
Fires when an asset or a new version of an existing asset is uploaded.
asset.deleted
Fires when asset deleted.
refdoc.uploaded
A new reference document uploaded.
refdoc.deleted
An existing reference document is deleted.
annotation.added
An annotation to asset is created.
annotation.edited
An annotation is edited.
annotation.deleted
An annotation is deleted.
task.created
A new task of any type is created.
task.completed
A task is marked as completed.
task.deleted
A task is deleted.
task.approved
An asset review task marked as approved.
task.rejected
An asset review task marked as rejected.
webhook.test
Dummy event object for testing endpoint.
project.created
Fires when a new project is created.
{
"EventId":"XppRxqUyNEqYrZtY9lRBdA",
"EventType":"project.created",
"Created":"2021-02-18T23:22:33.2944308Z",
"Data":{
"ProjectUID":"B0CADA6D72824F85A38BE8471503D204", // Unique ID of a newly created.
"Name":"ProjectName plain text" // Project name.
}
}
project.edited
Fires when one of the project’s attributes is changed: Name, Customer, Project, Design, Revision, Description, Tags, DueDate, ProjectOwners.
{
"EventId":"xDPuRZ1F_Ea03fO-WPZqnQ",
"EventType":"project.edited",
"Created":"2021-02-18T23:47:17.7572002Z",
"Data": {
"ProjectUID":"XXXXXXXXXXXXXXXXXX", // Unique ID of a project where the change made.
"Attribute":"Name", // Attribute name, see the list above.
"Value":"New project name" // New attribute value.
}
}
project.state
Fires when project’s state is changed, interactively or automatically by Approval Studio itself.
{
"EventId":"JvuKXVIPDE-V7wDZ9wPt9A",
"EventType":"project.state",
"Created":"2021-02-18T23:55:28.00321Z",
"Data": {
"ProjectUID":"XXXXXXXXXXXXXXXXXX", // Unique ID of a project.
"State":"Active|OnHold|Completed|InTransit|Archived" // New project's state.
}
}
asset.uploaded
Fires when an asset (or an asset version) is uploaded and successfully processed. If asset processing failed due any of possible reason, an event will not send.
Fires when an asset (or an asset version) is deleted.
Note: when an assets is deleted, all the related objects – tasks, comments, attachment are deleted as well, but you will not get separate webhook calls for them.
Fires when an annotation added in a proof tool to an asset.
This can be a high-level annotation associated with selected region on the image, or a comment (to an annotation).
{
"version": "1.0",
"statusCode": 200,
"message": "GET Request successful.",
"result": [
{
"webhookUID": "XXXXXXXXXXXXXXXXXXXX01",
"url": "http://xxxxx.com/part/of/url01",
"secret": "YYYYYYYYYYYYYYYYYYYYY01", // This secret will be sent with every POST in order
"created": "2021-02-09T09:17:27.904911" // to ensure that this is API host is posting.
},
{
"webhookUID": "XXXXXXXXXXXXXXXXXXXX02",
"url": "http://xxxxx.com/part/of/url02",
"secret": "YYYYYYYYYYYYYYYYYYYYY02",
"created": "2021-02-09T09:17:27.904911"
}
]
}
POST /api/v1/webhook
Sets us a new webhook. Note: The API host might need up to ~1 minute to start processing a newly installed webhook. Curl:
{
"version": "1.0",
"statusCode": 200,
"message": "POST Request successful.",
"result": {
"webhookUID": "XXXXXXXXXXXXXXXXXXXX01", // Newly assigned webhook ID.
"url": "http://xxxx.com/part/of/url", // Url of the webhook, as in the request.
"secret": "YYYYYYYYYYYYYYYYYYYYY01", // This secret will be sent with every POST in order
"created": "2021-02-09T09:17:27.904911" // to ensure that this is API host is posting,
// see HTTP response header "Api-Secret".
}
}
HTTP Code
Response
400
Error: Parameters’ validation failed.
See HTTP code 400 description.
412
Error: Webhook with the given URL is already registered for this tenant. API does not allow to setup duplicates.
DELETE /api/v1/webhook
Deletes a webhook with the given ID.
Note that deletion of a webhook might need up to ~1 minute to API host to update. Curl:
When posting test data, API host uses the same retry logic as it is for real calls, i.e. tries to re-deliver it in case of failure, so multiple calls are expected if the endpoint fails to accept the call instantly. Curl: