Bulk Create Links
Creates multiple links in a single request. Each link in the array follows the same schema as the Create Link endpoint. The API processes all items and returns both successfully created links and any errors.
POST
/v1/links/bulk links:write Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
links | object[] | Yes | Array of link objects to create (max 100). |
Each object in the links array accepts:
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Destination URL. |
custom_slug | string | No | Custom short code. |
labels | string[] | No | Array of labels (max 10 per link). |
routing_rules | object[] | No | Conditional routing rules. |
expires_at | string | No | ISO 8601 expiration datetime. |
Request Examples
curl -X POST https://xqr.co/api/v1/links/bulk \ -H "Authorization: Bearer xqr_pk_a1b2c3d4.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "links": [ { "url": "https://example.com/page-one", "custom_slug": "page1", "labels": ["batch-march"] }, { "url": "https://example.com/page-two", "custom_slug": "page2", "labels": ["batch-march"] }, { "url": "https://example.com/page-three", "labels": ["batch-march"] } ] }'const response = await fetch("https://xqr.co/api/v1/links/bulk", { method: "POST", headers: { Authorization: "Bearer xqr_pk_a1b2c3d4.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "Content-Type": "application/json", }, body: JSON.stringify({ links: [ { url: "https://example.com/page-one", custom_slug: "page1", labels: ["batch-march"] }, { url: "https://example.com/page-two", custom_slug: "page2", labels: ["batch-march"] }, { url: "https://example.com/page-three", labels: ["batch-march"] }, ], }),});
const { data } = await response.json();console.log(`Created: ${data.created.length}, Errors: ${data.errors.length}`);import httpx
response = httpx.post( "https://xqr.co/api/v1/links/bulk", headers={ "Authorization": "Bearer xqr_pk_a1b2c3d4.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "Content-Type": "application/json", }, json={ "links": [ {"url": "https://example.com/page-one", "custom_slug": "page1", "labels": ["batch-march"]}, {"url": "https://example.com/page-two", "custom_slug": "page2", "labels": ["batch-march"]}, {"url": "https://example.com/page-three", "labels": ["batch-march"]}, ] },)
data = response.json()["data"]print(f"Created: {len(data['created'])}, Errors: {len(data['errors'])}")Response
201 Created
Separate created and errors arrays.
{ "data": { "created": [ { "id": "e58f3a2b-9d4c-4b6e-af70-2345678901bc", "short_url": "https://xqr.co/page1", "short_code": "page1", "destination": "https://example.com/page-one", "enabled": true, "labels": ["batch-march"], "routing_rules": [], "scan_count": 0, "last_scan_at": null, "expires_at": null, "created_at": "2026-03-21T16:00:00Z", "updated_at": "2026-03-21T16:00:00Z" }, { "id": "f69g4b3c-ae5d-4c7f-b081-3456789012cd", "short_url": "https://xqr.co/page2", "short_code": "page2", "destination": "https://example.com/page-two", "enabled": true, "labels": ["batch-march"], "routing_rules": [], "scan_count": 0, "last_scan_at": null, "expires_at": null, "created_at": "2026-03-21T16:00:00Z", "updated_at": "2026-03-21T16:00:00Z" }, { "id": "a70h5c4d-bf6e-4d80-c192-4567890123de", "short_url": "https://xqr.co/x7kQ3mR", "short_code": "x7kQ3mR", "destination": "https://example.com/page-three", "enabled": true, "labels": ["batch-march"], "routing_rules": [], "scan_count": 0, "last_scan_at": null, "expires_at": null, "created_at": "2026-03-21T16:00:00Z", "updated_at": "2026-03-21T16:00:00Z" } ], "errors": [] }, "meta": { "request_id": "req_4d5e6f7089012345", "rate_limit": { "limit": 600, "remaining": 595, "reset": 1742572800 } }}When a link fails to create, its entry appears in the errors array:
{ "data": { "created": [], "errors": [ { "index": 0, "error": "conflict", "message": "The slug 'page1' is already in use." } ] }, "meta": { ... }}Was this page helpful?
Thanks for your feedback!