NAV

Introduction

Welcome to the Artwork API, a powerful tool that allows you to seamlessly integrate artworker.io into your workflow. With this API, you can create, update and attach artwork to artworker jobs.

You can view code examples in the dark area to the right.

Authentication

To authorize, use the api_key query param:

POST https://open-api.artworker.io/v1/route ?api_key=[API_KEY]

Make sure to replace [API_KEY] with your API key.

Artworker uses API keys to allow access to the API. You can register a new Artworker API key at our developer portal.

Artworker expects the API key to be included in all API requests to the server as a query parameter that looks like the following:

?api_key=[API_KEY]

Jobs

Job Object

Sample Job Object

{
    "id": "63e6357ad9a28b28ab9",
    "ref": "ODR1382",
    "name": "Flyers",
    "state": "created",
    "customerActionURL": "",
    "supplerActionURL": "https://app.artworker.io/artwork/63e6357ad9a28b28ab9",
}
Field Description
job.id The id of the job.
job.name The jobs name.
job.ref The jobs reference.
job.state The state of the current job.
job.customerActionURL URL for the customer to visit to perform any required action. Returns an empty string if no action required.
job.supplerActionURL URL for the supplier to visit to perform any required action. Returns an empty string if no action required.

Job States

awaiting_artwork

Job ready to recieve artwork

rejected

Artwork rejected by admin, waiting for customer to review

pending_approval

Artwork uploaded by customer or admin and awaiting review

ready_for_production

Artwork approved and ready for production

pending_proof_approval

Proof(s) sent to customer for approval

proof_rejected

Customer has rejected proof(s)

proof_accepted

Customer has accepted proof(s)

complete

Job marked as complete by admin

Create a Job

POST https://open-api.artworker.io /v1/job ?api_key=[API_KEY]

Headers

Content-Type: application/json

Sample Body

{
    "customerEmail": "[email protected]",
    "customerName": "John Doe",
    "jobName": "Flyers",
    "jobRef": "ODR1382",
    "mediaUrls": [
        "https://storage.cloud.google.com/artworker-api-docs/samples/model-3-leaflet.pdf"
    ]
}

Sample Response

{
    "job": {
        "id": "63e6357ad9a28b28ab9",
        "ref": "ODR1382",
        "name": "Flyers",
        "state": "created",
        "customerActionURL": "",
        "supplerActionURL": "https://app.artworker.io/artwork/63e6357ad9a28b28ab9",
    }
}

This endpoint creates a new job within artworker.

HTTP Request

POST https://open-api.artworker.io/v1/job?api_key=[API_KEY]

Body Parameters

Parameter Required Description
customerEmail true The customers email address.
customerName true The customers name.
jobName true A name for the job. This should (although does not have to be) be unique to prevent multiple jobs with the same name within artworker.
jobRef false A reference for the name, not used by our system but useful if you want to associate the job with an order number for example.
mediaUrls false URLs to artwork files to be imported into artworker and attached to this job. Must be publically accessible.

Response

Parameter Description
job.id The id of the job.
job.name The jobs name.
job.ref The jobs reference.
job.state The state of the current job.
job.customerActionURL URL for the customer to visit to perform any required action. Returns an empty string if no action required.
job.supplerActionURL URL for the supplier to visit to perform any required action. Returns an empty string if no action required.

Webhook_Endpoint

Webhook Endpoints

POST /v1/webhook_endpoint

GET /v1/webhook_endpoint/:id

POST /v1/webhook_endpoint/:id

GET /v1/webhook_endpoint

DELETE /v1/webhook_endpoint/:id

You can configure webhook endpoints via the API to be notified about events that happen in your Stripe account or connected accounts.

Most users configure webhooks from the dashboard, which provides a user interface for registering and testing your webhook endpoints.

Webhook Object

Sample Webhook Object

{
    "webhook": {
        "id": 1234,
        "url": "https://dev.example.com/api/webhook",
        "secret": "whsec_85n9845yt754n87y35",
        "enabledEvents": ["job.complete"]
    }
}
Field Description
id Unique identifier for the object.
url The URL of the webhook endpoint.
secret The endpoint’s secret, used to generate webhook signatures.
enabledEvents List of enabled events for this endpoint

Create a Webhook

POST https://open-api.artworker.io /v1/webhook_endpoint ?api_key=[API_KEY]

Headers

Content-Type: application/json

Sample Body

{
    "url": "https://dev.example.com/api/webhook",
    "enabledEvents": ["job.complete"]
}

Sample Response

{
    "webhook": WebhookObject
}

A webhook endpoint must have a url and a list of enabled_events. You can also create webhook endpoints in the webhooks section of the Settings page.

HTTP Request

POST https://open-api.artworker.io/v1/webhook_endpoint?api_key=[API_KEY]

Body Parameters

Parameter Required Description
url true The URL of the webhook endpoint.
enabledEvents true The list of events to enable for this endpoint.

Response Body

Field Description
webhook WebhookObject

Get a Webhook

GET https://open-api.artworker.io /v1/webhook_endpoint/1234 ?api_key=[API_KEY]

Headers

Content-Type: application/json

Sample Response

{
    "webhook": WebhookObject
}

This endpoint gets a single webhook by id.

HTTP Request

GET https://open-api.artworker.io/v1/webhook_endpoint/:id?api_key=[API_KEY]

Response Body

Field Description
webhook WebhookObject

Update a Webhook

POST https://open-api.artworker.io /v1/webhook_endpoint/1234 ?api_key=[API_KEY]

Headers

Content-Type: application/json

Sample Body

{
    "webhook": WebhookObject
}

Sample Response

{
    "webhook": WebhookObject
}

This endpoint updates a webhook within artworker.

HTTP Request

POST https://open-api.artworker.io/v1/webhook_endpoint/:id?api_key=[API_KEY]

Body Parameters

Parameter Required Description
webhook WebhookObject

Response Body

Field Description
webhook WebhookObject

List Webhooks

GET https://open-api.artworker.io /v1/webhook_endpoint/1234 ?api_key=[API_KEY]

Headers

Content-Type: application/json

Sample Response

{
    "webhooks": WebhookObject[]
}

This endpoint lists all the artworker accounts webhooks. There is a limit of 5 webhooks per account, so the max length of the returned array is 5.

HTTP Request

GET https://open-api.artworker.io/v1/webhook_endpoint?api_key=[API_KEY]

Response Body

Field Description
webhooks WebhookObject[]

Delete a Webhook

DELETE https://open-api.artworker.io /v1/webhook_endpoint/1234 ?api_key=[API_KEY]

Headers

Content-Type: application/json

Sample Response

{
    "ok": true
}

This endpoint deletes a webhook by id.

HTTP Request

DELETE https://open-api.artworker.io/v1/webhook_endpoint/:id?api_key=[API_KEY]

Response Body

Field Description
ok returns true if successfully deleted

Errors

The Artworker API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
404 Not Found -- The specified object could not be found.
405 Method Not Allowed -- You tried to access an invalid method.
406 Not Acceptable -- You requested a format that isn't json.
410 Gone -- The object requested has been removed from our servers.
418 I'm a teapot.
429 Too Many Requests -- You've reached the limit! Slow down!
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

Webhooks

Use incoming webhooks to get real-time updates

Listen for events on your Artworker account so your integration can automatically trigger reactions. Artworker uses webhooks to notify your application when an event happens in your account.

How Artworker uses webhooks

A webhook enables Artworker to push real-time notifications to your app. Artworker uses HTTPS to send these notifications to your app as a JSON payload. You can then use these notifications to execute actions in your backend systems.

Webhook Events

When an event occurs, we create a new Webhook Event Object object. If you registered a webhook endpoint to receive that event, we send it to your endpoint as part of a POST request.

Webhook Event Object

Sample Body

{
    "eventId": "29fdefd3-f499-49a5-8dae-db53b4321d41",
    "event": "job.complete",
    "createdAt": "2023-02-10T09:15:09.7345339Z",
    "data": {
        "id": "43991f5c-f75a-459d-9fd2-decaca579354",
        "name": "flyers",
        "ref": "order001",
        "state": "complete",
        "customerActionURL": "",
        "supplerActionURL": ""
    }
}
Parameter Description
eventID ID of the event.
event Webhook Events.
createdAt timestamp
data Job

Webhook Events

job.awaiting_artwork

Occurs when an admin sends an artwork request to a customer.

job.rejected

Occurs when an admin reject one of more files in a job.

job.pending_approval

Occurs when artwork has been uploaded either by the customer, or by the supplier and is ready for review.

job.ready_for_production

Occurs either when an admin has approved all artwork for a job, or when a customer has accepted provided fixup files or accepted highlighted issues.

job.pending_proof_approval

Occurs when an admin sends proof(s) to the customer

job.proof_rejected

Occurs when a customer rejects one or more proofs in a job

job.proof_accepted

Occurs when a customer approved all proofs in a job

job.complete

Occurs when an admin marks a job as complete

Steps to receive webhooks

  1. Identify the events you want to monitor, and the event payloads to parse.
  2. Create a webhook endpoint as an HTTP endpoint on your local server.
  3. Handle requests from Artworker by parsing each event object and returning 200 or 201 response status codes
  4. Test your webhook endpoint is working properly with ngrok
  5. Deploy your webhook endpoint so it's publicly accessible HTTPS URL
  6. Register your publicly accessible HTTPS URL in your Artworker account settings.

1: Identify the events to monitor

Use the list of events above (Webhook Events) to identify which events you want to recieve notification of and take a note of the event object payload.

2: Setting up locally

To get up and running locally, you will need

  1. A local application serving an endpoint like http://localhost:8080/artworker_webhooks
  2. To make this endpoint accessible to the internet

Route setup

const http = require('http');
const server = http.createServer((req, res) => {
  if (req.method === 'POST' && req.url === '/artworker_webhooks') {
    let body = '';
    req.on('data', chunk => { body += chunk.toString(); });
    req.on('end', () => {
      console.log(body);
      res.end('Event received');
    });
  } else {
    res.statusCode = 404;
    res.end('Not Found');
  }
});

server.listen(8080, () => {
  console.log('Server listening on http://localhost:8080');
});

Set up an HTTP endpoint on your local machine that can accept unauthenticated webhook requests with a POST method.

For a quick start, the code on the right is a small node app that starts a server on 8080 and accepts unauthenticated POST requests to http://localhost:8080/artworker_webhooks

Ngrok setup

Artworker cannot send events directly to your local system as the endpoint is not accessible to the internet. To change that ngrok can be used to route requests through a hosted endpoint to your local one. Once ngrok is installed from https://ngrok.com/, run the following command and make a note of the endpoint it outputs.

ngrok http 8080

Artworker setup

In the Artworker settings page, navigate to webhooks and create a new one with your ngrok url (dont forget to all the /artworker_webhooks to the end!) eg https://337f-86-175-154-122.ngrok.io/artworker_webhooks with the desired events.

Create a couple of test jobs and you should start to see events hitting the endpoint!

3: Handle events from Artworker

Check event objects

Each event is structured as an Webhook Event Object object with a event, eventId, and related Artworker resource nested under data. Your endpoint must check the event type and parse the payload of each event.

Return a 2xx response

Your endpoint should return a positive status code (2xx) quickly before executing any complicated procedures that might result in a timeout.

Built-in retries

Artworker's webhooks come equipped with automatic retry mechanisms for response status codes 3xx, 4xx, or 5xx. Artworker stop trying to deliver the request after 2 days.

Artworker has the option to authenticate the webhook events it sends to your endpoints by including a signature in the Artworker-Signature header of each event. This ensures that the events were sent by Artworker and not by an unauthorized third party.

To verify the signatures, you must first retrieve the secret for your endpoint from the Webhooks settings.

It's important to note that Artworker generates a unique secret key for each endpoint. If you have multiple endpoints, you will need to retrieve the secret for each one you want to verify signatures on.

Verifying signatures

Artworker-Signature:
t=1492774577,
v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

The Artworker-Signature header included in each signed event contains a timestamp and one signature. The timestamp is prefixed by t= and the signature by v1=


const artworkersig = req.headers['artworker-signature'];

let [timestamp, sig] = artworkersig.split(",")

timestamp = timestamp.replace("t=", "")
sig = sig.replace("v1=", "")

const stripeSecret = crypto.createHmac('sha256', STRIPE_SIGNING_SECRET)
  .update(`${timestamp}.${body}`)
  .digest('hex');

const verified = stripeSecret === sig

Artworker generates signatures using a hash-based message authentication code (HMAC) with SHA-256

Step 1: Extract the timestamp and signatures from the heade

Split the header, using the , character as the separator, to get a list of elements. Then split each element, using the = character as the separator, to get a prefix and value pair.

The value for the prefix t corresponds to the timestamp, and v1 corresponds to the signature (or signatures). You can discard all other elements.

Step 2: Prepare the signed_payload string

The signed_payload string is created by concatenating:

The timestamp (as a string) The character . The actual JSON payload (that is, the request body) Step 3: Determine the expected signature Compute an HMAC with the SHA256 hash function. Use the endpoint’s signing secret as the key, and use the signed_payload string as the message.

Step 4: Compare the signatures

Compare the signature (or signatures) in the header to the expected signature. For an equality match, compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your tolerance.

To protect against timing attacks, use a constant-time string comparison to compare the expected signature to each of the received signatures.

Preventing replay attacks

A replay attack occurs when a malicious party captures a legitimate payload and its accompanying signature and sends them again. To prevent such attacks, Artworker includes a timestamp in the Artworker-Signature header. This timestamp is part of the signed payload and is verified by the signature, making it impossible for the attacker to alter the timestamp without altering the signature. If the signature is still valid but the timestamp is outdated, your application can choose to reject the payload.

Artworker creates a new timestamp and signature each time it sends an event to your endpoint. In cases where Artworker retries sending an event (e.g., if your endpoint responded with a non-2xx status code on the previous attempt), a fresh signature and timestamp will be generated for the new delivery attempt.

PDF_Profile_Job

PDF Profile Job Endpoints

POST /v1/pdf-profile/job

GET /v1/pdf-profile/job/custom-uid/:custom-uid

You can submit a PDF to apply a predefined Callas profile, and generate new output PDFs. The job runs asynchronously, and users can poll a "profileJob" object to track the status.

PDF Profile Job Object

Sample PDF Profile Job Object

{
  "pdfProfileJob": {
    "createdAt": "2024-09-04T10:10:10Z",
    "updatedAt": "2024-09-04T10:15:15Z",
    "customUid": "unique-custom-uid-5-6",
    "state": "processing",
    "originalFilename": "model-3-leaflets-proofs.pdf",
    "originalUrl": "https://storage.googleapis.com/sample.pdf",
    "originalThumbnailUrl": "https://storage.googleapis.com/sample-thumbnail.jpg",
    "outputFiles": [
      {
        "url": "https://storage.googleapis.com/output1.pdf",
        "originalFilename": "output1.pdf",
        "thumbnailUrl": "https://storage.googleapis.com/output1-thumbnail.jpg"
      }
    ],
    "hasErrors": false,
    "timeline": [
      {
        "createdAt": "2024-09-04T10:11:00Z",
        "updatedAt": "2024-09-04T10:13:00Z",
        "action": "profile_applied",
        "error": ""
      }
    ],
    "profileName": "default",
    "configOptions": {}
  }
}
Field Description
createdAt The timestamp when the job was created.
updatedAt The timestamp when the job was last updated.
customUid A custom identifier provided by the user.
state The current state of the job.
originalFilename The original filename of the uploaded PDF.
originalUrl The URL of the original PDF file.
originalThumbnailUrl The URL of the thumbnail image of the original PDF.
outputFiles An array of output files generated by the profile. Each item in the array contains:
- url: The URL to access the output PDF file.
- originalFilename: The filename of the output PDF.
- thumbnailUrl: The URL to access a thumbnail of the output PDF.
hasErrors A boolean indicating if the job encountered errors.
timeline An array representing the history of actions performed on the job. Each item in the array contains:
- createdAt: The timestamp when the action occurred.
- updatedAt: The timestamp when the action was updated.
- action: The action performed on the job (e.g., profile_applied).
- error: Details of any error encountered during the action (if applicable).
profileName The name of the profile applied to the PDF.
configOptions Configuration options specific to the profile applied.

Profile Job States

PdfProfileJobStateUndefined

The job state is undefined. This typically indicates that the job has not yet been initialized or there is an issue with the job status.

PdfProfileJobStateImporting

The job is in the process of importing the PDF from the provided URL. This state covers downloading and preparing the PDF for processing.

PdfProfileJobStateQueued

The job has been queued for processing. It is waiting for available resources or a turn in the processing pipeline.

PdfProfileJobStateProcessing

The job is actively being processed. The profile is being applied to the PDF, and output files are being generated.

PdfProfileJobStateDone

The job has completed successfully. The processed PDF(s) and any related output files are available for download.

PdfProfileJobStateError

The job encountered an error during processing. The error details can be found in the timeline error fields, and no valid output files were generated.

Create a PDF Profile Job

POST https://open-api.artworker.io /v1/pdf-profile/job ?api_key=[API_KEY]

Headers

Content-Type: application/json

Sample Body

{
  "profileName": "default",
  "url": "https://storage.googleapis.com/assets-store/model-3-leaflets-proofs.pdf",
  "configOptions": {},
  "customUid": "unique-custom-uid-5-6",
  "outputBasename": "base123",
  "outputFilenames": ["file1.pdf", "file2.pdf"]
}

Sample Response

{
  "pdfProfileJob": {
    "createdAt": "2024-09-04T10:10:10Z",
    "updatedAt": "2024-09-04T10:15:15Z",
    "customUid": "unique-custom-uid",
    "state": "PdfProfileJobStateImporting",
    "originalFilename": "model-3-leaflets-proofs.pdf",
    "originalUrl": "https://storage.googleapis.com/kudo-assets-store/model-3-leaflets-proofs.pdf",
    "originalThumbnailUrl": "https://storage.googleapis.com/sample-thumbnail.jpg",
    "outputFiles": [],
    "hasErrors": false,
    "timeline": [],
    "profileName": "default",
    "configOptions": {}
  }
}

This endpoint initiates the PDF profiling job. The job applies a specified Callas profile to a PDF, provided via a URL, and returns a job object for tracking.

HTTP Request

POST https://open-api.artworker.io/v1/pdf-profile/job?api_key=[API_KEY]

Body Parameters

Parameter Required Description
profileName true The name of the Callas profile to apply to the PDF.
url true The URL of the PDF to apply the profile to.
configOptions false Configuration options specific to the chosen profile.
customUid false A user-provided unique identifier for tracking the job.
outputBasename false Basename for output files. Example - 'basefilename' will output "basefilename_0001.pdf" and "basefilename_0002.pdf" if 2 output files are generated.
outputFilenames false Array of output file names for each output file. Requires outputBasename to be set as a fallback.

Response Body

Field Description
pdfProfileJob PDF Profile Job Object

Get a PDF Profile Job by custom-uid

GET https://open-api.artworker.io /v1/pdf-profile/job/custom-uid/:custom-uid ?api_key=[API_KEY]&expand=timeline

Headers

Content-Type: application/json

Sample Response

{
  "pdfProfileJob": {
    "createdAt": "2024-09-04T10:10:10Z",
    "updatedAt": "2024-09-04T10:15:15Z",
    "customUid": "unique-custom-uid-5-6",
    "state": "PdfProfileJobStateDone",
    "originalFilename": "model-3-leaflets-proofs.pdf",
    "originalUrl": "https://storage.googleapis.com/sample.pdf",
    "originalThumbnailUrl": "https://storage.googleapis.com/sample-thumbnail.jpg",
    "outputFiles": [
      {
        "url": "https://storage.googleapis.com/output1.pdf",
        "originalFilename": "output1.pdf",
        "thumbnailUrl": "https://storage.googleapis.com/output1-thumbnail.jpg"
      }
    ],
    "hasErrors": false,
    "timeline": [
            {
                "createdAt": "2024-09-04T10:10:10Z",
                "updatedAt": "2024-09-04T10:10:10Z",
                "action": "PdfProfileJobActionImported",
                "error": ""
            },
            {
                "createdAt": "2024-09-04T10:10:10Z",
                "updatedAt": "2024-09-04T10:10:10Z",
                "action": "PdfProfileJobActionStartProcessing",
                "error": ""
            },
            {
                "createdAt": "2024-09-04T10:10:10Z",
                "updatedAt": "2024-09-04T10:10:10Z",
                "action": "PdfProfileJobActionDone",
                "error": ""
            }
    ],
    "profileName": "default",
    "configOptions": {}
  }
}

This endpoint retrieves the status and details of a specific PDF profile job by its custom-uid.

HTTP Request

GET https://open-api.artworker.io/v1/pdf-profile/job/:id?api_key=[API_KEY]

Query Parameters

Parameter Description
?expand=timeline populates the timeline array

Response Body

Field Description
pdfProfileJob PDF Profile Job Object

Task API

Workflows & Tasks

Processing files is done via workflows in the terminology of the Artworker REST API. Each workflow consists of one or more tasks.

For example: The first task of a workflow could be importing the file(s) from a specific source. The second task could be running a preflight process on the file(s).

It is possible to chain tasks and pass the output of one task to the next. This is useful if you want to add bleed and create a thumbnail or preview with the added bleed, for example.

Import Tasks

An import task is a task that imports one or multiple files into Artworker for use in other tasks. Examples of import tasks include downloading files from a URL. Imported files are only stored temporarily.

Typically, each workflow has at least one import task.

Errors and Rate Limiting

The Artworker API responds with standard HTTP status codes, such as 400 (invalid data), 500 (internal server error), 503 (temporarily unavailable), or 429 (too many requests).

Rate Limiting

Some endpoints enforce dynamic rate limiting. These endpoints return the X-RateLimit-Limit and X-RateLimit-Remaining headers. If the limit is reached, a 429 error is returned along with a Retry-After header that specifies the time in seconds to wait before making the next request.

Endpoints Currently Rate Limited:

Failed Workflows and Tasks

Workflows and tasks that complete with an error will have their status set to error. More about the error can be found in the error within each task, system errors are listed below. In addition to these check the task documentation for Task specific errors.

Error Code Description
0 Unknown system error.
1 A generic server error occurred.
2 The server is currently unavailable.
3 The request was malformed or invalid.
4 The server received an invalid response from the upstream server.
5 The gateway is currently unavailable.
30 The network request timed out.

Please do not automatically retry tasks. Artworker internally already retries tasks if there are retryable errors (such as network errors).

Create Workflows

POST https://open-api.artworker.io /v1/taskapi/workflows?api_key=[API_KEY]

Sample Body

{
  "uuid": "myworkflow-123",
  "tasks": {
    "import": {
      "operation": "import/URL",
      "payload": {
        "urls": ["https://storage.googleapis.com/kudo-web-assets/upload-examples/example_five.pdf"]
      }
    },
    "fixup": {
      "operation": "run/pdf-advanced-edit",
      "input": "import",
      "payload": {
        "pageRange": "1",
        "options":{
          "removePrinterMarks": {
            "enabled": true
          }
        }
      }
    }
  }
}

Create a workflow with one ore more tasks. This endpoint is asynchronous and responds immediately

Parameter Type Required Description
tasks array [task] true The example consists of two tasks: import-my-file and preflight-my-file. You can name these tasks however you want, but only alphanumeric characters, -, and _ are allowed in the task names. Each task has an operation (for example: import/url or preflight). The input parameter allows it to directly reference the name of another task created within the same workflow request. If a task changes the PDF in some way (e.g., adds bleed), then it will output a new PDF; a task with a specified input will use the output of the previous task. This allows you to chain tasks together and create a workflow for your files.
uuid string false A string to identify the workflow, used for associating it with an ID in your application without affecting functionality.

Get a Workflow

GET https://open-api.artworker.io /v1/taskapi/workflows/100?api_key=[API_KEY]

Sample Response

{
  "id": 100,
  "uuid": "myworkflow-123",
  "status": "completed",
  "createdAt": "2024-12-18T11:00:03.721923Z",
  "endedAt": "2024-12-18T11:00:06.642034Z",
  "tasks": [
    {
      "id": 200,
      "operation": "import/URL",
      "name": "import",
      "payload": {
        "urls": [
          "https://storage.googleapis.com/kudo-web-assets/upload-examples/example_five.pdf"
        ]
      },
      "status": "completed",
      "error": null,
      "createdAt": "2024-12-18T11:00:03.725411Z",
      "startedAt": "2024-12-18T11:00:03.725411Z",
      "endedAt": "2024-12-18T11:00:03.811505Z",
      "links": {
        "self": "https://open-api.artworker.io/workflow/100/task/import"
      }
    },
    {
      "id": 201,
      "operation": "run/pdf-advanced-edit",
      "name": "fixup",
      "dependsOn": "import",
      "payload": {
        "options": {
          "removePrinterMarks": {
            "enabled": true
          }
        },
        "pageRange": "1"
      },
      "status": "completed",
      "error": null,
      "createdAt": "2024-12-18T11:00:03.725411Z",
      "startedAt": "2024-12-18T11:00:03.725411Z",
      "endedAt": "2024-12-18T11:00:03.811505Z",
      "links": {
        "self": "https://open-api.artworker.io/workflow/100/task/fixup",
        "files": [
          "https://open-api.artworker.io/workflow/100/task/import/files/1"
        ]
      }
    }
  ],
  "links": {
    "self": "https://open-api.artworker.io/workflow/100"
  }
}

This endpoint is asynchronous and immediately responds the workflow status, even if the workflow has not completed yet.

Returns

Field Type Description
id int Unique identifier of the workflow.
uuid string User-defined unique ID to track the workflow.
status string Current status of the workflow: one of pending, running, completed, or error.
tasks array List of tasks in the workflow. See the "Get Tasks" endpoint for task model details.
createdAt string ISO 8601 timestamp when the workflow was created.
endedAt string ISO 8601 timestamp when the workflow finished.
links object Links for this workflow. Always contains self

Get a Task

Get https://open-api.artworker.io /v1/taskapi/workflows/100/task/fixup?api_key=[API_KEY]

Sample Response

{
  "id": 201,
  "operation": "run/pdf-advanced-edit",
  "name": "fixup",
  "dependsOn": "import",
  "payload": {
    "options": {
      "removePrinterMarks": {
        "enabled": true
      }
    },
    "pageRange": "1"
  },
  "status": "completed",
  "error": null,
  "createdAt": "2024-12-18T11:00:03.725411Z",
  "startedAt": "2024-12-18T11:00:03.725411Z",
  "endedAt": "2024-12-18T11:00:03.811505Z",
  "links": {
    "self": "https://open-api.artworker.io/workflow/100/task/fixup",
    "files": [
      "https://open-api.artworker.io/workflow/100/task/import/files/1"
    ]
  }
}

Returns

Field Type Description
id int Unique identifier of the task.
operation string Name of the operation, for example import/URL or run/pdf-advanced-edit.
dependsOn string Name of previous task in workflow.
payload object Your submitted payload for the tasks. Depends on the operation type.
status string Current status of the task: one of pending, running, completed, or error.
createdAt string ISO 8601 timestamp when the task was created.
startedAt string ISO 8601 timestamp when the task started.
endedAt string ISO 8601 timestamp when the task finished.
links object Links for this task. Always contains self but frequently contains a list of files depending on the operation. Each link to a file returns the result of the task for the specified file

Tasks

Import from URL Task

POST https://open-api.artworker.io /v1/taskapi/workflows?api_key=[API_KEY]

Sample Body

{
  "uuid": "myworkflow-123",
  "tasks": {
    "import": {
      "operation": "import/URL",
      "payload": {
        "urls": ["https://storage.googleapis.com/kudo-web-assets/upload-examples/example_five.pdf"]
      }
    },
    ...
  }
}

This task accepts a list of urls of files to import into the Artworker system. Each job must start with an import task.

Operation

import/URL

Options

Field Type Description
urls string array List of urls of files to import ready for processing.

Results

There are no results available for this operation

Advanced PDF Edit Task

POST https://open-api.artworker.io /v1/taskapi/workflows?api_key=[API_KEY]

Sample Body

{
  "uuid": "myworkflow-123",
  "tasks": {
    "fixup": {
      "operation": "run/pdf-advanced-edit",
      "input": "import",
      "payload": {
        "pageRange": "1",
        "outputFilenames": [{
          "fileNum": 1,
          "outputFilename": "output.pdf"
        }],
        "options":{
          "removePrinterMarks": {
            "enabled": true
          },
          "removeContentOutsideBleed": {
            "enabled": true
          },
          "addCropMarks": {
            "enabled": false
          },
          "pageRotation": {
            "enabled": false,
            "angle": 0,
            "pageSelector": ""
          },
          "removePage": {
            "enabled": false,
            "pageSelector": ""
          },
          "addPage": {
            "enabled": false,
            "beforeAfter": "After",
            "pageSelector": "1",
            "numberOfCopies": 1,
            "copyContent": false
          },
          "splitPage": {
            "enabled": false,
            "pageSelector": "1*",
            "reorderPage": false
          },
          "bleedboxFixGeometry": {
            "enabled": true
          },
          "optimisePDF": {
            "enabled": true
          },
          "renameLayer": {
            "enabled": false,
            "layerRegEx": ".*",
            "newName": ""
          },
          "removeLayer": {
            "enabled": false,
            "layerRegEx": ".*"
          },
          "removeContentFromLayer": {
            "enabled": true
          },
          "flattenLayers": {
            "enabled": false
          },
          "splitInHalf": {
            "enabled": false
          },
          "readerSpreads": {
            "enabled": false,
            "coverPage": true
          },
          "resizePage": {
            "enabled": false,
            "width": 210,
            "height": 297,
            "method": "homothetical"
          },
          "generateBleed": {
            "enabled": true,
            "sizeLeft": 3.0,
            "sizeRight": 3.0,
            "sizeTop": 3.0,
            "sizeBottom": 3.0,
            "minCheck": 80.0,
            "method": "mirror",
            "generateOnLayer": true,
            "bleedLayerName": "generatedBleed"
          },
          "embedOutputIntent": {
            "enabled": true,
            "outputIntent": "ISO Coated v2 300% (ECI)"
          },
          "convertRegistrationToBlack": {
            "enabled": false
          },
          "knockoutWhite": {
            "enabled": true,
            "applyTo": "Vector-Text"
          },
          "overprintBlackText": {
            "enabled": true,
            "minTextSize": 9.0
          },
          "convertTextToOutlines": {
            "enabled": false
          }
        }
      }
    }
  }
}

This task accepts a list of urls of files to import into the Artworker system. Each job must start with an import task.

Operation

run/pdf-advanced-edit

Payload

Field Type Description
pageRange string schema Range of pages to apply changes to. See page selector
outputFilenames array [{ "fileNum": 1, "outputFilename": "output.pdf"}] Array of filenames with specific file numbers
options object list of pdf preflight options, see below for details

Document

REMOVE PRINTER MARKS

Printer marks (crop marks and other registration elements) will be detected (as mush as it is possible in an automated process) and removed. This cannot be turned off.

REMOVE CONTENT OUTSIDE BLEED

Any content present outside the bleed box will be removed. This cannot be turned off.

ADD CROP MARKS

Crop marks, aligned on the trim box, can be added. Please note that this action will happen near the end of the process, once the trimbox and the bleedbox have been correctly setup.

Field Type Description Required Default
addCropMarks.enabled Boolean Activate or deactivate the fixup false false
ROTATE PAGE(S)

PDF pages can be rotated by a specific angle, defined by the variable rotateAngle. The default value is 0. The selection of pages can be passed as the variable pageSelector (see page-selector schema).

Field Type Description Required Default
pageRotation.enabled Boolean Activate or deactivate the fixup false false
pageRotation.angle Number Angle for rotation (0, 90, 180, or 270) false 0
pageRotation.pageSelector String schema List of pages to be rotated false ""
REMOVE PAGE(S)

PDF pages can be removed. The selection of pages can be passed as the variable pageSelector (see page-selector schema).

Field Type Description Required Default
removePage.enabled Boolean Activate or deactivate the fixup false false
removePage.pageSelector String schema List of pages to be removed false ""
ADD PAGE(S)

PDF pages can be added. Pages are added before or after each current selected page. This is defined with the variable bedforeAfter. The default value is After. The selection of pages is passed to the fixup using the variable pageSelector (see page-selector schema). This fixup can add a copy of the current page (which allows duplication) or a blank page, according the variable copyContent. The default value is false, which means that a blank page will be added. With the variable numberOfCopies, it is possible to duplicate the page(s) more than one time. The default value is 1, which means one copy.

Field Type Description Required Default
addPage.enabled Boolean Activate or deactivate the fixup false false
addPage.beforeAfter String Add the page before or after the current page (“Before”/“After”) false After
addPage.pageSelector String schema List of pages where pages will be added false 1
addPage.numberOfCopies Number Number of times the page should be duplicated false 1
addPage.copyContent Boolean Whether the added page is blank or a copy of the current page false false
SPLIT AND REORDER PAGES

The PDF file can be split into separate PDF files. The split scheme is passed using the variable pageSelector (see page-selector schema). The default value is 1*, which means every page. Merging the pages again at the end of the process results of a reordering of the pages. This is triggered by the variable reorderPage.

Field Type Description Required Default
splitPage.enabled Boolean Activate or deactivate the fixup false false
splitPage.pageSelector String schema Split scheme false 1*
splitPage.reorderPage Boolean Activate or deactivate the reordering instead of split false false
SET BLEED AND GEOMETRY BOXES

Geometry boxes, and in particular bleedbox can be setup. This one is very important for the bleed generation to be performed. It should always be on.

Field Type Description Required Default
bleedboxFixGeometry.enabled Boolean Activate or deactivate the fixup false true
OPTIMISE PDF

The PDF is optimised for fast web view, so it can be served more quickly over the Internet by a web server that supports byte serving.

Field Type Description Required Default
optimisePDF.enabled Boolean Activate or deactivate the fixup false true

Layers

RENAME LAYER

Layers (optional content group) can be renamed in the PDF file. The list of the layers to be renamed is controlled by the variable layerRegEx, which is a regular expression (to give the most flexible options). The layer(s) will be renamed to the variable newName.

Field Type Description Required Default
renameLayer.enabled Boolean Activate or deactivate the fixup false false
renameLayer.layerRegEx String Regular expression to match layers to be renamed false .*
renameLayer.newName String Defines the new name of the layer(s) false ""
REMOVE LAYER

Layers (optional content group) can be removed from the PDF file. The list of the layers to be removed is controlled by the variable layerRegEx, which is a regular expression (to give the most flexible options). The layer can be removed with and without the actual content on the layer, controlled by the variable toggleRemoveContentFromLayer. The default value is 1, which means that the content will also be removed from the file.

Field Type Description Required Default
removeLayer.enabled Boolean Activate or deactivate the fixup false false
removeLayer.layerRegEx String Regular expression to match layers to be removed false .*
Field Type Description Required Default
removeContentFromLayer.enabled Boolean Whether the content has to be removed as well false true
FLATTEN LAYERS

Layers (optional content group) can be flattened. Please note that that this action will also remove any content on hidden layer(s).

Field Type Description Required Default
flattenLayers.enabled Boolean Activate or deactivate the fixup false false

Pages

SPLIT IN HALF

The PDF pages can be split in half. This action recognises if the page is a single or a double page automatically.

Field Type Description Required Default
splitInHalf.enabled Boolean Activate or deactivate the fixup false false
READER SPREADS

This action arranges the pages in two-page spread without reordering the pages. A cover page (single page) can be used during the process (to keep book spreads), this is controlled by the variable coverPage. The default value is true, which means that the cover page will be used.

Field Type Description Required Default
readerSpreads.enabled Boolean Activate or deactivate the fixup false false
readerSpreads.coverPage Boolean Uses a cover page (single page) during the process false true

Dimensions

RESIZE PAGE

There are two resize options, you can resize homothetically or by stretching the artwork to fit the targeted dimensions. this is controlled by the variable resizeMethod. Possible values are homothetical and stretch to fit. When the resize is homothetic, the artwork is resized to fit the complete artwork into the new dimension. White space may be visible left and right or top and bottom, if the new size is not nomothetical to the original size. The process plan can handle all combinations, portrait on portrait, landscape on landscape, portrait on landscape and landscape on portrait. The requested size of the artwork’s trimbox is defined by the variables targetPageWidth and targetPageHeight. The default values are 210mm wide by 297mm tall.

Field Type Description Required Default
resizePage.enabled Boolean Activate or deactivate the fixup false false
resizePage.width Number Target width of the trimbox of the artwork false 210
resizePage.height Number Target height of the trimbox of the artwork false 297
resizePage.method String Method for resize: "homothetical" or "stretch to fit" false homothetical
GENERATE BLEED

The requested size of the bleed is defined by side, with the corresponding variables bleedSizeLeft, bleedSizeRight, bleedSizeTop and bleedSizeBottom. The default value is 3mm for all sides. If existing, the bleedbox will be resized to the value of the trimbox + bleedSize(side), cropbox and mediabox will be adjusted accordingly.

CHECK BLEED

First of all, the PDF file is checked to find out if bleed is necessary (white background on the edges does not require any bleed), then it will be checked to see if enough bleed is present (bleed size should be equal or bigger than bleedSize(side)). If this is the case, the existing bleed will be kept. The minimum required bleed (size that is acceptable, even if less than the requested size) is controlled by the variable bleedMinCheck. The default value is 80 (80%). Note 1: for example for a 3mm requested bleed, the acceptable bleed size would be 2.4mm if the value is 80%. Note 2: to force check to the required bleed size (no tolerance), use the value 100 (100%). If there is no bleed or there is not enough bleed, the engine will generate the missing bleed. If there is enough bleed, no bleed will be generated. If the existing bleed is bigger than the requested bleed, the over-bleed content will be removed and the bleedbox will be set to the requested size.

GENERATE BLEED

The necessary bleed will be generated at bleedSize(side) bleed size (for each side). The method for bleed generation can be “mirror”, “pixel repetition” or “stretch”. The algorithm is controlled by the variable bleedMethod. The default value is mirror. To improve the visual result of the bleed, the generated bleed will start where existing content stops. It can be at trimbox (if there is no bleed at all), or away from trimbox (if there was some bleed, but not enough). To ease selection of generated bleed (e.g. for removal if not good enough), the bleed can be generated on a specific layer (controlled by the variable onLayer), named after the variable bleedLayerName. The default value is generatedBleed.

Field Type Description Required Default
generateBleed.enabled Boolean Activate or deactivate the fixup false true
generateBleed.sizeLeft Number Size of the bleed on the left side of the page false 3.0
generateBleed.sizeRight Number Size of the bleed on the right side of the page false 3.0
generateBleed.sizeTop Number Size of the bleed on the top side of the page false 3.0
generateBleed.sizeBottom Number Size of the bleed on the bottom side of the page false 3.0
generateBleed.minCheck Number Acceptable bleed size from required bleed size (%) false 80.0
generateBleed.method String Method for bleed generation: "mirror", "pixel repetition", or "stretch" false mirror
generateBleed.generateOnLayer Boolean Activate bleed generation on a specific layer false true
generateBleed.bleedLayerName String Name of the bleed layer if generated on a specific layer false generatedBleed

Colours

EMBED OUTPUT INTENT

Output intent can be embedded in the file. The output intent is selected from a fixed list (the list can be updated but this requires a modification of the process plan) and defined by the variable outputIntent. The default value is ISO Coated v2 300% (ECI).

Field Type Description Required Default
embedOutputIntent.enabled Boolean Activate or deactivate the fixup false true
embedOutputIntent.outputIntent String Defines the output intent to be embedded. The value can be 'ISO Coated v2 300% (ECI)', 'ISO Coated v2 (ECI)', 'PSO Uncoated ISO12647 (ECI)', 'PSO Coated v3 (ECI)', or 'PSO Uncoated v3 (ECI)' false ISO Coated v2 300% (ECI)
CONVERT REGISTRATION TO BLACK INSIDE TRIMBOX

If registration colour has been used inside the trimbox by mistake, it can be converted to black, on overprint.Black text can be setup on overprint to avoid mis-registration when placed on a coloured background. This is particularly useful for small texts. The minimum text size under which the overprint must be setup is controlled by the variable overprintBlackTextMinimumSize. The default value is 9.

Field Type Description Required Default
convertRegistrationToBlack.enabled String Activate or deactivate the fixup false ISO Coated v2 300% (ECI)

Overprinting

KNOCKOUT WHITE TEXT AND/OR VECTOR OBJECTS

White objects (vector objects and/or text) can be improperly setup to overprint, which means that the object will not be visible anymore. This fixup corrects the overprint flag by putting it on knockout. The fixup can be applied to text, vector objects, or both, according to the variable applyKnockoutWhite. The default value is Vector-Text.

Field Type Description Required Default
knockoutWhite.enabled Boolean Activate or deactivate the fixup false true
knockoutWhite.applyTo String Defines on which objects the fixup will perform. The value can be “Text”, “Vector” or “Vector-Text” false Vector-Text
OVERPRINT BLACK TEXT

Black text can be setup on overprint to avoid mis-registration when placed on a coloured background. This is particularly useful for small texts. The minimum text size under which the overprint must be setup is controlled by the variable overprintBlackTextMinimumSize. The default value is 9.

Field Type Description Required Default
overprintBlackText.enabled Boolean Activate or deactivate the fixup false true
overprintBlackText.minTextSize Number The text size under which the overprint will be set up false 9.0

Fonts

CONVERT TEXT TO OUTLINES

This fixup will outline fonts. Please note that some fonts may still remain as live text, if the font’s license does not allow to outline.

Field Type Description Required Default
convertTextToOutlines.enabled Boolean Activate or deactivate the fixup false false

Results

GET https://open-api.artworker.io /v1/taskapi/workflows/100/task/fixup/files/1?api_key=[API_KEY]

Sample Response

{
  "output_file_url": "https://storage.cloud.google.com/preflight-profile-output-bucket/123/d39b0efe-9982-4161-bbd0-1074a8169d8f.pdf",
  "output_filename": "some-output.pdf",
  "report": {
    "bleedboxFixGeometry": {
      "details": {
        "message": "",
        "numFail": 0,
        "numPass": 6
      },
      "retCode": 5
    }
  }
}

The results will be available at /v1/taskapi/workflows/:workflowId/task/:taskName/files/:fileNumber

Task Error Codes

This section covers error codes found in the task.error object that are specific to this task.

Error Code Description
503, 508 At least one error executing fixups.
100 - 104 An error occurred starting fixups.
105, 106, 107 The provided file is encrypted or damaged and in need of repair.
130 - 159 Fixups were terminated prematurely. Please contact support

Response

Field Type Description
output_file_url String URL of created file
output_filename String If provided, custom output filename
report object If provided, custom output filename

Details

Field Type Description
message String error or warning message if available
numFail Number Number of fails
numPass Number Number of passes

RetCode

Code Number Description
0 No hit, no Fixups executed
1 At least one hit with severity ‘info’, no Fixups executed
2 At least one hit with severity ‘warning’, no Fixups executed
3 At least one hit with severity ‘error’, no Fixups executed
5 No hit, Fixups have been executed
6 At least one hit with severity ‘info’, Fixups have been executed
7 At least one hit with severity ‘warning’, Fixups have been executed
8 At least one hit with severity "error", Fixups have been executed; Fixups failed

Page Selector

A split scheme expression can be a number with an asterisk * or a more complex string.

Number with Asterisk *

Simple Expressions

Type Syntax Example Description
Simple expression number[-number] 1-5 Pages 1 to 5: [1,2,3,4,5]
5-1 Pages 5 to 1 in reverse: [5,4,3,2,1]
8 Only page 8
-1 Last page
-3--1 Last 3 pages: [n, n-1, n-2]
-1--3 Last 3 pages in reverse: [n-2, n-1, n]
-1-3 Last n - 2 pages in reverse: [n, ..., 3]

Simple Expression with Simple Range

Type Syntax Example Description
Simple expression with Simple Range number[-number]_number[-number]["," joker$] 1-2_-2--1 First 2 and last 2 pages: [1,2,n-1,n]
1-2_-2--1,$ First 2, last 2, and remaining inner pages: [1,2,n-1,n,3,...,n-2]
1_1_1_1 4 times page 1: [1,1,1,1]

Multipage Expressions

Type Syntax Example Description
Even pages even_pages even All even pages (same as *2(2))
Odd pages uneven_pages odd All odd pages (same as *2(1))
Packages of pages number*[(start_page)] 5* Packages of 5 pages
5*(2) Packages of 5 pages, starting with page 2
Every nth page *number[(start_page)] *5 Every 5th page
*5(2) Every 5th page, starting with page 2
*5(-20) Every 5th page of the last 20 pages (total 4 pages)
*number[(start_page,end_page)] *5(2,20) Every 5th page, starting from page 2 to page 20

Simple Expression List

Type Syntax Example Description
Simple expression list simple_expression {"," simple_expression}[ "," joker$] 1-5,8,-3--1 Pages 1-5, page 8, and the last 3 pages of the PDF
1-5,8,-1--3 Pages 1-5, page 8, and the last 3 pages in reverse order
1-5,8,$ Pages 1-5, page 8, and all remaining pages

Joker Expression

Type Syntax Example Description
Joker <expression>,$ 1-5,8,-3--1,$ Pages 1-5, page 8, the last 3 pages, and the rest of the pages of the PDF, grouped separately.

Summary

These expressions allow flexible page selection and grouping for PDF manipulation. The syntax supports: 1. Simple expressions (specific pages or ranges). 2. Complex combinations (e.g., ranges with joker $). 3. Patterns for regular intervals (e.g., every 5th page).