API Reference · v1

The Fable Editor API

Everything you design in Fable Editor is available programmatically. Render templates with live data, pull projects into your build pipeline and export HTML, MJML or PDF straight from your own systems.

Base URLhttps://api.fableditor.com/v1

Introduction

The Fable Editor API is organized around REST. It uses predictable resource URLs, accepts JSON request bodies, returns JSON responses and uses standard HTTP status codes and verbs. All requests must be made over HTTPS; plain HTTP requests are refused.

Every object has a stable, prefixed ID such as prj_ for projects and exp_ for exports, so you can tell what an ID refers to at a glance. Timestamps are Unix epoch seconds in UTC.

Authentication

Authenticate by sending your secret API key as a bearer token in the Authorization header. Keys start with fbl_live_ and are issued to your organization when your Unlimited Edition subscription starts.

Authenticated requestcurl
curl https://api.fableditor.com/v1/me \
  -H "Authorization: Bearer fbl_live_..."
Your API key grants full read and write access to your organization's workspace. Keep it on the server, store it in a secrets manager and never expose it in browser or mobile code.

Requests with a missing or invalid key return 401 Unauthorized. Requests made with a key whose subscription is no longer active return 403 Forbidden.

Errors

Codes in the 2xx range indicate success, 4xx indicates a problem with the request and 5xx indicates a problem on our side. Every error response has the same shape, including a request_id you can share with support.

Error objectjson
{
  "error": {
    "type": "invalid_request",
    "code": "parameter_missing",
    "message": "The format parameter is required.",
    "param": "format",
    "request_id": "req_8fK2cQ1x"
  }
}
StatusMeaning
200 OKThe request succeeded.
202 AcceptedThe job was queued. Poll the returned object for its status.
400 Bad RequestThe request was malformed or a parameter was invalid.
401 UnauthorizedNo valid API key was provided.
403 ForbiddenThe key is valid but its subscription is not active.
404 Not FoundThe requested object does not exist in your workspace.
409 ConflictAn idempotency key was reused with different parameters.
429 Too Many RequestsYou exceeded the rate limit. Retry after the time in Retry-After.
5xxSomething went wrong on our side. These are safe to retry with backoff.

Pagination

List endpoints return results in pages using cursor based pagination. Pass limit (1 to 100, default 20) and, to fetch the next page, starting_after set to the ID of the last object you received. The response includes has_more to tell you whether another page exists.

List responsejson
{
  "object": "list",
  "data": [ ... ],
  "has_more": true,
  "next_cursor": "prj_3Hq8vLw2"
}

Idempotency

All POST requests accept an Idempotency-Key header. If a request with the same key is received again within 24 hours, the original response is returned instead of performing the action twice. Use a random UUID per logical operation so network retries never create duplicate exports.

Idempotent requestcurl
curl https://api.fableditor.com/v1/projects/prj_3Hq8vLw2/exports \
  -H "Authorization: Bearer fbl_live_..." \
  -H "Idempotency-Key: 5f1c7e2a-9b3d-4c8e-a1f0-2d6b8e4c9a71" \
  -H "Content-Type: application/json" \
  -d '{ "format": "pdf" }'

Rate limits

Requests are rate limited per API key. Every response includes headers describing your current allowance, so your client can slow down before it hits the limit.

HeaderDescription
RateLimit-LimitRequests allowed in the current window.
RateLimit-RemainingRequests left in the current window.
RateLimit-ResetSeconds until the window resets.
Retry-AfterSent with 429 responses. Seconds to wait before retrying.

Versioning

The API version is part of the URL. Within v1 we only make additive changes: new endpoints, new optional parameters and new fields on responses. Build your client to ignore fields it does not recognize. Breaking changes ship as a new major version, and the previous version keeps working with advance notice before retirement.

Account

Inspect the organization and subscription bound to the API key you are using. This is the quickest way to confirm a key works.

GET/v1/me

Retrieve account

Takes no parameters.

Requestcurl
curl https://api.fableditor.com/v1/me \
  -H "Authorization: Bearer fbl_live_..."
Response200
{
  "object": "account",
  "organization": {
    "id": "org_7Tn4pXe9",
    "name": "Acme Corporation"
  },
  "plan": "unlimited",
  "subscription_status": "active",
  "current_period_end": 1822291200
}

Projects

A project is anything built in Fable Editor: an email template, an interactive form or a document. Projects carry their design, their variables and their publishing state.

GET/v1/projects

List projects

ParameterDescription
typestringOnly return projects of this type: email, form or document.
updated_aftertimestampOnly return projects changed after this time. Useful for incremental syncs.
limitintegerPage size, 1 to 100. Defaults to 20.
starting_afterstringCursor for the next page. See Pagination.
Requestcurl
curl "https://api.fableditor.com/v1/projects?type=email&limit=2" \
  -H "Authorization: Bearer fbl_live_..."
Response200
{
  "object": "list",
  "data": [
    {
      "id": "prj_3Hq8vLw2",
      "object": "project",
      "type": "email",
      "name": "Order confirmation",
      "updated_at": 1790688000
    },
    {
      "id": "prj_9Rb1kDs6",
      "object": "project",
      "type": "email",
      "name": "Monthly newsletter",
      "updated_at": 1790601600
    }
  ],
  "has_more": true,
  "next_cursor": "prj_9Rb1kDs6"
}
GET/v1/projects/{id}

Retrieve a project

Returns a single project, including the variables it expects when rendered.

Requestcurl
curl https://api.fableditor.com/v1/projects/prj_3Hq8vLw2 \
  -H "Authorization: Bearer fbl_live_..."
Response200
{
  "id": "prj_3Hq8vLw2",
  "object": "project",
  "type": "email",
  "name": "Order confirmation",
  "variables": [
    { "name": "first_name", "type": "string", "required": true },
    { "name": "order_id", "type": "string", "required": true },
    { "name": "items", "type": "array", "required": false }
  ],
  "created_at": 1788009600,
  "updated_at": 1790688000
}

Rendering

Merge data into a project and get the finished output back in a single synchronous call. Rendering is what you call from your application at send time, for example right before handing an email to your mail provider.

POST/v1/projects/{id}/render

Render a project

ParameterDescription
formatstring requiredhtml for inbox ready HTML with inlined CSS, or text for the plain text alternative.
variablesobjectValues for the project's variables. Missing required variables return 400.
localestringLocale used for dates and numbers, such as en-US or da-DK.
Requestcurl
curl https://api.fableditor.com/v1/projects/prj_3Hq8vLw2/render \
  -H "Authorization: Bearer fbl_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "format": "html",
    "locale": "en-US",
    "variables": {
      "first_name": "Ada",
      "order_id": "A1042"
    }
  }'
Response200
{
  "object": "render",
  "project": "prj_3Hq8vLw2",
  "format": "html",
  "subject": "Your order A1042 is confirmed",
  "content": "<!doctype html><html>...",
  "size_bytes": 48213
}

Exports

Exports produce downloadable files from a project. They run asynchronously: create an export, then retrieve it until its status is succeeded and a download URL is available.

POST/v1/projects/{id}/exports

Create an export

ParameterDescription
formatstring requiredhtml, mjml or pdf.
variablesobjectOptional data to merge before exporting.
Requestcurl
curl https://api.fableditor.com/v1/projects/prj_3Hq8vLw2/exports \
  -H "Authorization: Bearer fbl_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "format": "pdf" }'
Response202
{
  "id": "exp_5Wc2mJa8",
  "object": "export",
  "project": "prj_3Hq8vLw2",
  "format": "pdf",
  "status": "processing",
  "created_at": 1790774400
}
GET/v1/exports/{id}

Retrieve an export

Status is one of processing, succeeded or failed. Download URLs are signed and expire after one hour; retrieve the export again for a fresh URL.

Requestcurl
curl https://api.fableditor.com/v1/exports/exp_5Wc2mJa8 \
  -H "Authorization: Bearer fbl_live_..."
Response200
{
  "id": "exp_5Wc2mJa8",
  "object": "export",
  "project": "prj_3Hq8vLw2",
  "format": "pdf",
  "status": "succeeded",
  "url": "https://files.fableditor.com/exp_5Wc2mJa8.pdf?sig=...",
  "url_expires_at": 1790778000,
  "created_at": 1790774400
}

Get your API key

Every Unlimited Edition subscription includes full API access for your organization.

Get started