Skip to content

Creating links in bulk

The create endpoint always takes an array. One link is an array of one; the maximum is 50 per request.

Why 50

Each request writes every link plus a campaign counter in a single database transaction, and that transaction has a hard ceiling. Fifty is what fits with room for the counter. Asking for 51 returns 413 BATCH_TOO_LARGE rather than silently truncating — chunk and repeat.

Matching results to your rows

Set reference on each entry — any string of your own, up to 128 characters. It is echoed back on both successes and failures, so you can match results to your rows without trusting array order.

json
{
  "links": [
    { "reference": "crm-8821", "metadata": { "customer_id": "acct_1" } },
    { "reference": "crm-8822", "metadata": { "customer_id": "acct_2" } }
  ]
}

One bad row does not fail the batch

By default a batch is best-effort. Valid entries are created, invalid ones are reported, and the response is 207 Multi-Status:

json
{
  "created": 1,
  "failed": 1,
  "items": [
    { "index": 0, "reference": "crm-8821", "status": "created", "url": "https://survey.zefi.ai/…" },
    {
      "index": 1,
      "reference": "crm-8822",
      "status": "error",
      "error": {
        "code": "VALIDATION_FAILED",
        "detail": "metadata.author_email: author_email is not a valid email address"
      }
    }
  ]
}

Check status per item. A 207 is not a failure — it means read the list.

All-or-nothing

Send "on_error": "abort" to get today's stricter behaviour: if any entry is invalid the request returns 400 and nothing is created.

json
{ "on_error": "abort", "links": [  ] }

Use it when a partial batch would be worse than no batch — a nightly job you would rather re-run clean than reconcile.

Zefi API v1