Skip to content
JamFrame
Docs menu

Delivery and runs

Send each rendered file to a link list, your webhook or a Slack channel, then test, run and cancel a workflow and read its run history when something fails.

After a workflow renders a row, its deliver steps send the file on. This page covers the three deliveries, then how runs work: testing, the run history, canceling, what happens when something fails, and how to hear about it.

Deliveries

To add one, use + Add a delivery under the render step. To remove one, select it and click Remove this step.

  • A workflow needs at least one delivery. Render URL is the simplest.
  • You can add several. Every rendered row goes through each of them, in order.
  • If one delivery fails, the others still run.
  • Each delivery counts as one step toward your plan’s step limit.
Delivery What it does
Render URL Keeps a link to each file in the run history and in the API.
Send to a webhook Sends each row and its file links to your URL as JSON.
Post to Slack Posts a message with the image to a Slack channel.

Render URL

Each render’s file link is kept with its row. You see the files in the Run history tab, and your code gets them from the Workflows API. Links work for an hour each time you open the run history or read the run, and the files are deleted 8 days after the render. See How long files last.

Send to a webhook

JamFrame sends a POST request to your URL for each rendered row.

  1. Click + Add a delivery and pick Send to a webhook.
  2. Under Webhook URL, type your endpoint, such as https://hooks.example.com/renders. It must use https:// and be reachable from the internet.
  3. Save.

The body is JSON:

{
  "event": "workflow.row.rendered",
  "workflow": { "id": "cm3k9x2ab0001", "name": "Quote cards" },
  "run": { "id": "cm3k9y7cd0004", "trigger": "schedule" },
  "row": {
    "index": 0,
    "values": { "Quote": "Stay hungry", "Author": "Jobs" }
  },
  "render": {
    "id": "cm3k9z1ef0007",
    "format": "png",
    "url": "https://cdn.jamframe.com/renders/…/0.png?Expires=…",
    "urls": ["https://cdn.jamframe.com/renders/…/0.png?Expires=…"]
  }
}
  • row.index counts from 0 in the run. row.values holds every column of the row.
  • render.url is the first file. render.urls has one link per file, for example one per page.
  • run.trigger is manual, schedule, webhook, new_rows or api.

The request has the headers Content-Type: application/json and User-Agent: JamFrame-Webhook/1. It isn’t signed. To check that a call comes from your workflow, put a long secret in the URL, such as https://hooks.example.com/renders?token=…, and check it on your side.

Any 2xx answer counts as delivered. If your endpoint doesn’t answer within 10 seconds, can’t be reached, or answers 429 or 5xx, JamFrame tries once more after 2 seconds. Other answers aren’t tried again.

Post to Slack

Posts one message per row to a Slack channel, with the image.

  1. In Slack, add an incoming webhook to your channel: Apps → Incoming Webhooks → add it to a channel. Copy its URL. It starts with https://hooks.slack.com/services/.
  2. In the builder, click + Add a delivery and pick Post to Slack.
  3. Paste the URL under Slack incoming webhook URL. It’s stored encrypted, and afterwards the box only says it’s saved. Type a new URL to replace it.
  4. Optional: write the Message. Leave it empty for “New render from” followed by the workflow’s name and the link.
  5. Save.

In the message, you can use:

You write Becomes
{{Column}} The row’s value in that column, such as {{Name}}
{{render.url}} The link to the file
{{render.id}} The render’s id

For example: New quote card for {{Author}}: {{render.url}}. A message can be up to 3,000 characters. PNG, JPEG and WebP images show in the message itself. For a PDF, the message has only the link, which works for 7 days.

If Slack refuses the message because the webhook was removed or its channel archived, the delivery fails and says so. Make a new incoming webhook in Slack and paste its URL.

Runs

A run reads the source once, applies the transforms, then renders and delivers row by row.

Start a run

  • Run Now starts a run with every row.
  • Test with 1 row starts a run with only the first row. Use it to check the mapping and the deliveries before you render everything.

Both save your changes first, and both open the Run history tab. While a run is going, the list updates every few seconds.

A run needs render credits to start. A test run counts as a run toward your plan’s runs a month, and its row uses credits like any render.

Read the run history

Click the Run history tab under the steps. Runs are listed newest first. Each one shows:

  • its status (below), when it started and what started it: Run Now, Schedule, Webhook, New rows or API;
  • the rows that went through out of all rows, then the failed rows, the skipped rows and the credits;
  • the reason, when the run stopped early;
  • notes, such as “Test run: only the first 1 row ran.” or a note that your plan’s rows-per-run limit left rows out.

Click a run to see each row: its row number, its status, its first values, its images (click one to open it), the error if it failed, and the outcome of each delivery with its message. Click Older runs at the bottom to see more.

Run status What it means
Queued Waiting to start, for example behind other runs.
Running Rendering and delivering rows.
Succeeded Every row rendered and delivered.
Partly succeeded Some rows failed, the others went through.
Failed No row went through, or the source couldn’t be read.
Canceled Someone canceled the run.
Row status What it means
Waiting Not started yet.
Running Rendering or delivering now.
Succeeded Rendered, and every delivery worked.
Partly succeeded Rendered, but a delivery failed.
Failed The render failed. No credits were used.
Skipped The run stopped or was canceled before this row.

Cancel a run

Under a queued or running run, click Cancel run. A row that is rendering finishes. Rows that haven’t started are skipped.

When something fails

What happens Result
The source has a passing problem, such as a time-out or a busy server JamFrame tries again after about 1 minute, then after about 5 minutes. If it still fails, the run fails.
The source can’t be read, for example a sheet that isn’t shared The run fails at once. The run history says why.
The source is empty, or the transforms leave no rows The run succeeds with the note “No rows to process”.
A row’s render fails, for example a broken image link That row fails, uses no credits, and the run goes on with the next row.
A delivery fails The row is Partly succeeded. The row’s other deliveries still run.
Render credits run out The run stops. The rows left are skipped.
The template was deleted The run stops. The rows left are skipped.

Rows that fail aren’t tried again by themselves. Fix the cause, then run the workflow again. Keep in mind that a new run renders every row again, not only the failed ones.

Hear when a run ends

Your server can get a webhook event when a run ends:

  • workflow.run.completed: the run Succeeded, Partly succeeded or was Canceled.
  • workflow.run.failed: the run Failed.

Subscribe to them on the Webhooks page, under Developers in the sidebar. The event’s data is the run, with its counts, credits and status, plus workflowName. To set up and check webhooks, see Webhooks.

Credits

  • Each render uses 1 render credit per image, or per page of a PDF.
  • Failed renders are free.
  • AI layers in the template use AI credits too.
  • Deliveries cost nothing.

See Credits.

What next

  • Start and check runs from your own code: Workflows API.
  • See every render a workflow made: Renders.

Last updated

Still stuck?

Email [email protected] and a real person will reply. Tell us the template you were using and what you expected to happen.