{"info":{"name":"CaptiFi Connect API","description":"Send and receive SMS with UK numbers.\n\nAuthenticate with `Authorization: Bearer <api key>`. Keys starting `cc_live_` send real texts; keys starting `cc_test_` send nothing, simulate delivery a few seconds later (webhooks included) and charge no credit.\n\nSuccessful responses are `{ \"data\": ..., \"meta\": ... }`. Errors are `{ \"error\": { \"code\", \"message\", \"details\" } }` with a stable `code`. A path that does not exist answers `404` with `not_found`, and a body that is not valid JSON answers `400` with `invalid_json`.\n\nEvery response carries an `X-Request-Id` header. A `500` (`internal_error`) repeats it as `error.request_id`; quote it if you contact support.\n\nLists are newest first. Pass `meta.next_cursor` back as `cursor` for the next page.\n\nPOST /messages and POST /messages/bulk accept an `Idempotency-Key` header: a retry with the same key and body returns the first answer instead of sending again. Keys are kept for 24 hours; after that the same key starts a new send.\n\nSend request bodies as JSON (`Content-Type: application/json`), up to 1 MB (12 MB for sender name details, which can carry files).\n\nEach key can make 20 requests a second (burst 40), and all of an account's keys together 40 a second (burst 80). Responses carry `X-RateLimit-Limit` (the burst) and `X-RateLimit-Remaining` (what is left of it) for whichever limit is closer to running out. A `429` carries `Retry-After` in seconds.\n\nTest keys send to at most 50 numbers a request and 300 an hour. A test key can send test texts to typed numbers, quote, look up numbers, read and cancel the test texts and batches it sent, and manage webhooks that receive only test events. It cannot read live data: contacts, lists, opt-outs, conversations, link clicks and live texts answer `403` with `test_key_live_data`, and any other change is refused with `test_mode_not_supported`. 07700 900002 always comes back undelivered, 07700 900003 replies, and 07700 900004 replies STOP.\n\nAn API key can be limited to a scope: `full` (everything), `send` (send, bulk send, quote, look up, and read or cancel only the texts and batches it sent) or `read` (GET requests only); anything else answers `403` with `insufficient_scope`. A key can also have an expiry (`401` `key_expired` after it) and a list of IP addresses or CIDR ranges it may be used from (`403` `ip_not_allowed` from anywhere else).\n\nWebhooks are signed: `X-Connect-Signature: t=<unix seconds>,v1=<hex>`, where v1 is HMAC-SHA256 of `<t>.<raw body>` with your webhook secret. Reject a timestamp more than five minutes old. For 24 hours after a secret is rotated the header carries two v1 values, the old secret's first and the new one's last: accept the request when any v1 matches.\n\nAn endpoint that fails every delivery for three days is switched off (`enabled: false`, `auto_disabled_at` set) and the account owner is emailed. Turn it back on with PATCH, then send failed deliveries again with POST /webhooks/{id}/deliveries/{delivery_id}/retry.\n\nSet the collection variables baseUrl and api_key before sending a request.","schema":"https://schema.getpostman.com/json/collection/v2.1.0/collection.json","version":"1.0.0"},"auth":{"type":"bearer","bearer":[{"key":"token","value":"{{api_key}}","type":"string"}]},"variable":[{"key":"baseUrl","value":"https://captificonnect.co.uk/api/v1","type":"string"},{"key":"api_key","value":"","type":"string"}],"item":[{"name":"Messages","description":"Send texts and read what was sent and received.","item":[{"name":"Send a different text to each number","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Idempotency-Key","value":"","description":"Up to 200 characters. Makes a retried call safe for 24 hours.","disabled":true}],"url":{"raw":"{{baseUrl}}/messages/bulk","host":["{{baseUrl}}"],"path":["messages","bulk"]},"body":{"mode":"raw","raw":"{\n  \"messages\": [\n    {\n      \"to\": \"07412 000001\",\n      \"body\": \"Hi {first_name}, your table for 4 is at 7pm.\",\n      \"client_ref\": \"booking-1042\",\n      \"vars\": {\n        \"first_name\": \"Priya\"\n      }\n    },\n    {\n      \"to\": \"07412 000002\",\n      \"body\": \"Your order 881 is ready to collect.\",\n      \"client_ref\": \"order-881\"\n    }\n  ],\n  \"sender\": \"BISTRO\",\n  \"expires_in\": 3600\n}","options":{"raw":{"language":"json"}}},"description":"Up to 1,000 texts in one call and one batch, each with its own `to`, `body`, `client_ref` and `vars` (merge values: first_name, last_name, email, phone and any custom field). `sender`, `schedule_at`, `append_opt_out`, `track_links`, `expires_in` and `smart_encoding` apply to them all.\n\nEvery item is checked on its own. `data.results` has one entry per item, in order: `accepted` with its `message_id`, or `rejected` with a `reason` (the rejection reasons of POST /messages, or `invalid_item` with `errors` when the item itself is malformed). Only accepted items are charged. When none can be sent the call fails with `no_valid_recipients` and every item in `details.rejected`.\n\nAn `Idempotency-Key` covers the whole call. Credits, opt-outs, quiet hours and refunds work exactly as for POST /messages to typed numbers. The same number may appear more than once with different texts; the same number with the same text twice is a `duplicate`."},"response":[]},{"name":"Check a number before you text it","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/lookup","host":["{{baseUrl}}"],"path":["lookup"]},"body":{"mode":"raw","raw":"{\n  \"phone\": \"07412 000001\"\n}","options":{"raw":{"language":"json"}}},"description":"Free, and answered from the numbering plan and your own records: no network is asked, so it says nothing about whether the phone is switched on. `type` comes from the UK prefix (07 is mobile, 01 and 02 landline, anything else other), so a number keeps its type when it moves network. `rejection` is what POST /messages would say about it, or null when it can be sent to."},"response":[]},{"name":"List messages","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/messages","host":["{{baseUrl}}"],"path":["messages"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true},{"key":"direction","value":"","description":"","disabled":true},{"key":"status","value":"","description":"","disabled":true},{"key":"q","value":"","description":"A number (any format) or text to find in the body.","disabled":true},{"key":"number","value":"","description":"Only texts to or from this number, in any format.","disabled":true},{"key":"campaign_id","value":"","description":"","disabled":true},{"key":"batch_id","value":"","description":"","disabled":true},{"key":"client_ref","value":"","description":"","disabled":true},{"key":"since","value":"","description":"A date (YYYY-MM-DD, the whole day in UK time) or a date-time.","disabled":true},{"key":"until","value":"","description":"A date (YYYY-MM-DD, the whole day in UK time) or a date-time.","disabled":true}]},"description":"A test key lists only the test texts it sent, and the simulated replies to them."},"response":[]},{"name":"Send texts","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Idempotency-Key","value":"","description":"Up to 200 characters. Makes a retried request safe for 24 hours.","disabled":true},{"key":"Prefer","value":"","description":"Send `respond-async` (or `async: true` in the body) with more than 1,000 recipients to get `202` and the batch at once, while the send runs in the background. Follow it with GET /batches/{id}.","disabled":true}],"url":{"raw":"{{baseUrl}}/messages","host":["{{baseUrl}}"],"path":["messages"]},"body":{"mode":"raw","raw":"{\n  \"to\": [\n    \"07412 000001\",\n    \"+447412000002\"\n  ],\n  \"body\": \"Hi {first_name}, your order is ready.\",\n  \"client_ref\": \"order-881\"\n}","options":{"raw":{"language":"json"}}},"description":"Sends one text to every recipient given in `to`, `contact_ids` and `list_id` together. Numbers are checked and de-duplicated; refused numbers are listed in `rejected` and not charged. Merge fields such as {first_name} are filled from contacts. Credits are taken when the request is accepted (one per SMS part) and refunded for any text that fails before leaving."},"response":[]},{"name":"Price a send without sending","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/messages/quote","host":["{{baseUrl}}"],"path":["messages","quote"]},"body":{"mode":"raw","raw":"{\n  \"to\": \"\",\n  \"contact_ids\": [],\n  \"list_id\": \"\",\n  \"segment_id\": \"\",\n  \"body\": \"\",\n  \"template_id\": \"\",\n  \"sender\": \"\",\n  \"from\": \"\",\n  \"schedule_at\": \"1970-01-01T00:00:00.000Z\",\n  \"client_ref\": \"\",\n  \"append_opt_out\": false,\n  \"ignore_quiet_hours\": false,\n  \"track_links\": false,\n  \"expires_in\": 60,\n  \"smart_encoding\": false,\n  \"async\": false,\n  \"source\": \"campaign\"\n}","options":{"raw":{"language":"json"}}},"description":"Takes the same body as POST /messages and returns what it would charge. Add `\"source\": \"campaign\"` to price the text as a campaign launch sends it: a campaign can go by another route than a one-off send, which can change the opt-out line and so the parts, and it keeps to the quiet hours unless `ignore_quiet_hours` is true."},"response":[]},{"name":"Get a message with its status timeline","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/messages/:id","host":["{{baseUrl}}"],"path":["messages",":id"],"variable":[{"key":"id","value":"","description":"The message id."}]},"description":"A test key reads only the test texts it sent; a live text answers `403` `test_key_live_data`. A send-scoped key reads only the texts it sent."},"response":[]},{"name":"Remove a text's body","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/messages/:id","host":["{{baseUrl}}"],"path":["messages",":id"],"variable":[{"key":"id","value":"","description":"The message id."}]},"description":"Replaces the body with `[redacted]` for good. The message stays, with its status, parts and cost, so reports and billing still add up; `redacted_at` says when, and the account activity log says who. A text that has not left yet answers `409` `not_redactable`: cancel it first. Doing it again changes nothing."},"response":[]},{"name":"Cancel a scheduled text","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/messages/:id/cancel","host":["{{baseUrl}}"],"path":["messages",":id","cancel"],"variable":[{"key":"id","value":"","description":"The message id."}]},"description":"Works while the text is scheduled or still queued. Its credits are refunded and `message.cancelled` is raised. A test or send-scoped key cancels only texts it sent."},"response":[]},{"name":"Export messages as CSV","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/messages/export","host":["{{baseUrl}}"],"path":["messages","export"]},"description":"Accepts the list filters. Up to 50,000 rows."},"response":[]}]},{"name":"Conversations","description":"Two-way threads: one per number that replied or that you texted on its own from the dashboard, with your team's notes and who looks after each.","item":[{"name":"Mark a conversation unread","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/conversations/:phone/unread","host":["{{baseUrl}}"],"path":["conversations",":phone","unread"],"variable":[{"key":"phone","value":"","description":"As for GET /conversations/{phone}: the number URL-encoded in any common form, or a sender name."}]},"description":"The newest text they sent counts as unread again, so the thread shows as unread until someone reads it. `marked_unread` is 0 when nothing they sent was read (or they have sent nothing)."},"response":[]},{"name":"List the notes on a conversation","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/conversations/:phone/notes","host":["{{baseUrl}}"],"path":["conversations",":phone","notes"],"variable":[{"key":"phone","value":"","description":"As for GET /conversations/{phone}: the number URL-encoded in any common form, or a sender name."}]},"description":"Notes your team left on the thread, oldest first. Notes are never sent to the contact and never appear in webhooks."},"response":[]},{"name":"Add a note to a conversation","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/conversations/:phone/notes","host":["{{baseUrl}}"],"path":["conversations",":phone","notes"],"variable":[{"key":"phone","value":"","description":"As for GET /conversations/{phone}: the number URL-encoded in any common form, or a sender name."}]},"body":{"mode":"raw","raw":"{\n  \"body\": \"Asked for a table for six on Friday. Called back to confirm.\"\n}","options":{"raw":{"language":"json"}}},"description":"A note added with an API key has no `author_user_id` and is named after the key. Only the person who wrote a note can change or delete it, from the dashboard."},"response":[]},{"name":"Change a note","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/conversations/:phone/notes/:id","host":["{{baseUrl}}"],"path":["conversations",":phone","notes",":id"],"variable":[{"key":"phone","value":"","description":"As for GET /conversations/{phone}: the number URL-encoded in any common form, or a sender name."},{"key":"id","value":"","description":"The note id."}]},"body":{"mode":"raw","raw":"{\n  \"body\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"Only the person who wrote the note, signed in to the dashboard. Anyone else, and any API key, gets `403`."},"response":[]},{"name":"Delete a note","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/conversations/:phone/notes/:id","host":["{{baseUrl}}"],"path":["conversations",":phone","notes",":id"],"variable":[{"key":"phone","value":"","description":"As for GET /conversations/{phone}: the number URL-encoded in any common form, or a sender name."},{"key":"id","value":"","description":"The note id."}]},"description":"Only the person who wrote the note, signed in to the dashboard. Anyone else, and any API key, gets `403`."},"response":[]},{"name":"List conversations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/conversations","host":["{{baseUrl}}"],"path":["conversations"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true},{"key":"unread","value":"","description":"","disabled":true},{"key":"q","value":"","description":"","disabled":true},{"key":"assigned_to","value":"","description":"Only conversations given to this team member (a user id), `none` for those nobody has, or `me` (dashboard sign-ins only) for your own.","disabled":true}]},"description":"One entry per number that has texted you, or that you texted on its own from the dashboard (Send SMS to one number, or the inbox), newest activity first. Numbers you only reached in a bulk send, a campaign or through the API are left out until they reply."},"response":[]},{"name":"Get one conversation","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/conversations/:phone","host":["{{baseUrl}}"],"path":["conversations",":phone"],"variable":[{"key":"phone","value":"","description":"The number, URL-encoded: E.164 (%2B447412000001), 447412000001 or 07412000001 all find the same thread. A sender name (a bank, say) as it appears."}]},"description":"Get one conversation"},"response":[]},{"name":"Assign a conversation","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/conversations/:phone","host":["{{baseUrl}}"],"path":["conversations",":phone"],"variable":[{"key":"phone","value":"","description":"As for GET /conversations/{phone}: the number URL-encoded in any common form, or a sender name."}]},"body":{"mode":"raw","raw":"{\n  \"assigned_to_user_id\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"Gives the thread to a team member, or back to nobody with `null`. The person given it gets a notification in the dashboard. API keys, owners and admins can assign anyone on the account; a member signed in to the dashboard can take a thread themselves and let go of their own."},"response":[]},{"name":"Mark a conversation read","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/conversations/:phone/read","host":["{{baseUrl}}"],"path":["conversations",":phone","read"],"variable":[{"key":"phone","value":"","description":"As for GET /conversations/{phone}."}]},"description":"Mark a conversation read"},"response":[]}]},{"name":"Contacts","description":"Your address book.","item":[{"name":"List custom field keys","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/contacts/fields","host":["{{baseUrl}}"],"path":["contacts","fields"]},"description":"The keys of your custom fields, so a text can merge them as `{key}`. GET /custom-fields gives each with its name and type."},"response":[]},{"name":"Export contacts as CSV","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/contacts/export","host":["{{baseUrl}}"],"path":["contacts","export"],"query":[{"key":"q","value":"","description":"","disabled":true},{"key":"list_id","value":"","description":"","disabled":true}]},"description":"Every contact (or those matching `q` or `list_id`), newest first, with the names of its lists, whether the number is on the opt-out list, and the permission record (`consent_source`, `consent_at`, `consent_wording`). Custom fields are one JSON column (`custom`) and then one column each, headed by the field key, after `updated_at`; a date reads YYYY-MM-DD. Written as it is read, so large address books are fine."},"response":[]},{"name":"Delete contacts in bulk","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/contacts/bulk-delete","host":["{{baseUrl}}"],"path":["contacts","bulk-delete"]},"body":{"mode":"raw","raw":"{\n  \"contact_ids\": [\n    \"con_01J9Z8X7W6V5T4S3R2Q1P0N9M7\",\n    \"con_01J9Z8X7W6V5T4S3R2Q1P0N9M8\"\n  ]\n}","options":{"raw":{"language":"json"}}},"description":"Deletes up to 1,000 contacts in one go, all or none. Ids that are not contacts on this account (already deleted, or never there) are counted in `not_found` and do not stop the rest. Texts to and from the contacts stay in the message log, and they come off every list. Opt-outs are kept."},"response":[]},{"name":"List contacts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/contacts","host":["{{baseUrl}}"],"path":["contacts"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true},{"key":"q","value":"","description":"","disabled":true},{"key":"list_id","value":"","description":"","disabled":true}]},"description":"List contacts"},"response":[]},{"name":"Create a contact","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/contacts","host":["{{baseUrl}}"],"path":["contacts"]},"body":{"mode":"raw","raw":"{\n  \"phone\": \"07412 000001\",\n  \"first_name\": \"Priya\",\n  \"last_name\": \"Shah\"\n}","options":{"raw":{"language":"json"}}},"description":"Create a contact"},"response":[]},{"name":"Get a contact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/contacts/:id","host":["{{baseUrl}}"],"path":["contacts",":id"],"variable":[{"key":"id","value":"","description":"The contact id."}]},"description":"Get a contact"},"response":[]},{"name":"Update a contact","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/contacts/:id","host":["{{baseUrl}}"],"path":["contacts",":id"],"variable":[{"key":"id","value":"","description":"The contact id."}]},"body":{"mode":"raw","raw":"{\n  \"phone\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"Update a contact"},"response":[]},{"name":"Delete a contact","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/contacts/:id","host":["{{baseUrl}}"],"path":["contacts",":id"],"variable":[{"key":"id","value":"","description":"The contact id."}]},"description":"Delete a contact"},"response":[]},{"name":"Import contacts","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/contacts/import","host":["{{baseUrl}}"],"path":["contacts","import"]},"body":{"mode":"raw","raw":"{\n  \"rows\": []\n}","options":{"raw":{"language":"json"}}},"description":"Upserts up to 20,000 rows by number. Blank fields leave stored values alone."},"response":[]}]},{"name":"Lists","description":"Groups of contacts.","item":[{"name":"List lists","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/lists","host":["{{baseUrl}}"],"path":["lists"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true}]},"description":"List lists"},"response":[]},{"name":"Create a list","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/lists","host":["{{baseUrl}}"],"path":["lists"]},"body":{"mode":"raw","raw":"{\n  \"name\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"Create a list"},"response":[]},{"name":"Get a list","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/lists/:id","host":["{{baseUrl}}"],"path":["lists",":id"],"variable":[{"key":"id","value":"","description":"The list id."}]},"description":"Get a list"},"response":[]},{"name":"Rename a list","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/lists/:id","host":["{{baseUrl}}"],"path":["lists",":id"],"variable":[{"key":"id","value":"","description":"The list id."}]},"body":{"mode":"raw","raw":"{\n  \"name\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"Rename a list"},"response":[]},{"name":"Delete a list (contacts stay)","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/lists/:id","host":["{{baseUrl}}"],"path":["lists",":id"],"variable":[{"key":"id","value":"","description":"The list id."}]},"description":"Delete a list (contacts stay)"},"response":[]},{"name":"List members","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/lists/:id/contacts","host":["{{baseUrl}}"],"path":["lists",":id","contacts"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true}],"variable":[{"key":"id","value":"","description":"The list id."}]},"description":"List members"},"response":[]},{"name":"Add members","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/lists/:id/contacts","host":["{{baseUrl}}"],"path":["lists",":id","contacts"],"variable":[{"key":"id","value":"","description":"The list id."}]},"body":{"mode":"raw","raw":"{\n  \"contact_ids\": [],\n  \"phones\": []\n}","options":{"raw":{"language":"json"}}},"description":"By contact id or by number (new numbers become contacts)."},"response":[]},{"name":"Remove a member","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/lists/:id/contacts/:contactId","host":["{{baseUrl}}"],"path":["lists",":id","contacts",":contactId"],"variable":[{"key":"id","value":"","description":"The list id."},{"key":"contactId","value":"","description":""}]},"description":"Remove a member"},"response":[]}]},{"name":"Campaigns","description":"One text to a whole list or segment.","item":[{"name":"A campaign's report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/campaigns/:id/report","host":["{{baseUrl}}"],"path":["campaigns",":id","report"],"variable":[{"key":"id","value":"","description":"The campaign id."}]},"description":"What became of a campaign's texts and what people did after: texts by status, why the ones not delivered were not, link taps, and replies and opt-outs in the 7 days from when it started. Replies and opt-outs count each person once."},"response":[]},{"name":"List campaigns","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/campaigns","host":["{{baseUrl}}"],"path":["campaigns"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true},{"key":"series_id","value":"","description":"Only the runs of this recurring campaign.","disabled":true}]},"description":"List campaigns"},"response":[]},{"name":"Create a draft campaign","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/campaigns","host":["{{baseUrl}}"],"path":["campaigns"]},"body":{"mode":"raw","raw":"{\n  \"name\": \"\",\n  \"body\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"Create a draft campaign"},"response":[]},{"name":"Get a campaign","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/campaigns/:id","host":["{{baseUrl}}"],"path":["campaigns",":id"],"variable":[{"key":"id","value":"","description":"The campaign id."}]},"description":"Get a campaign"},"response":[]},{"name":"Edit a draft","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/campaigns/:id","host":["{{baseUrl}}"],"path":["campaigns",":id"],"variable":[{"key":"id","value":"","description":"The campaign id."}]},"body":{"mode":"raw","raw":"{\n  \"name\": \"\",\n  \"body\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"Edit a draft"},"response":[]},{"name":"Delete a draft","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/campaigns/:id","host":["{{baseUrl}}"],"path":["campaigns",":id"],"variable":[{"key":"id","value":"","description":"The campaign id."}]},"description":"Delete a draft"},"response":[]},{"name":"Send or schedule a draft","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/campaigns/:id/send","host":["{{baseUrl}}"],"path":["campaigns",":id","send"],"variable":[{"key":"id","value":"","description":"The campaign id."}]},"body":{"mode":"raw","raw":"{\n  \"schedule_at\": \"1970-01-01T00:00:00.000Z\",\n  \"ignore_quiet_hours\": false\n}","options":{"raw":{"language":"json"}}},"description":"Send or schedule a draft"},"response":[]},{"name":"Cancel a scheduled or sending campaign","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/campaigns/:id/cancel","host":["{{baseUrl}}"],"path":["campaigns",":id","cancel"],"variable":[{"key":"id","value":"","description":"The campaign id."}]},"description":"Texts not yet taken by a route are cancelled and refunded."},"response":[]}]},{"name":"Templates","description":"Saved texts.","item":[{"name":"List templates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/templates","host":["{{baseUrl}}"],"path":["templates"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true},{"key":"q","value":"","description":"","disabled":true}]},"description":"List templates"},"response":[]},{"name":"Create a template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/templates","host":["{{baseUrl}}"],"path":["templates"]},"body":{"mode":"raw","raw":"{\n  \"name\": \"\",\n  \"body\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"Create a template"},"response":[]},{"name":"Get a template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/templates/:id","host":["{{baseUrl}}"],"path":["templates",":id"],"variable":[{"key":"id","value":"","description":"The template id."}]},"description":"Get a template"},"response":[]},{"name":"Update a template","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/templates/:id","host":["{{baseUrl}}"],"path":["templates",":id"],"variable":[{"key":"id","value":"","description":"The template id."}]},"body":{"mode":"raw","raw":"{\n  \"name\": \"\",\n  \"body\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"Update a template"},"response":[]},{"name":"Delete a template","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/templates/:id","host":["{{baseUrl}}"],"path":["templates",":id"],"variable":[{"key":"id","value":"","description":"The template id."}]},"description":"Delete a template"},"response":[]}]},{"name":"Opt-outs","description":"Numbers that must not be texted.","item":[{"name":"Import an opt-out list","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/opt-outs/import","host":["{{baseUrl}}"],"path":["opt-outs","import"]},"body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"phone\": \"07412 000001\",\n      \"note\": \"Unsubscribed in our old system\"\n    },\n    {\n      \"phone\": \"+447412000002\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"description":"Adds up to 20,000 numbers in one go, for example a suppression list from another system. Send the rows of a parsed CSV (`{ \"rows\": [{ \"phone\": \"...\", \"note\": \"...\" }] }`, as the contacts import does), `{ \"phones\": [...] }`, or a plain array of numbers. Numbers in any common format are normalised; ones that cannot be read are listed in `invalid` and not stored. Numbers already on the list keep their record, so importing the same file twice changes nothing. Texts not yet sent to an added number are cancelled and refunded."},"response":[]},{"name":"Numbers taken off the opt-out list","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/opt-outs/removals","host":["{{baseUrl}}"],"path":["opt-outs","removals"],"query":[{"key":"limit","value":"","description":"1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true}]},"description":"The record kept each time a number is taken off the list: when, by whom (a login or an API key), the reason given, and how the number had opted out. Newest first."},"response":[]},{"name":"List opt-outs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/opt-outs","host":["{{baseUrl}}"],"path":["opt-outs"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true},{"key":"since","value":"","description":"Only opt-outs added at or after this time.","disabled":true},{"key":"q","value":"","description":"","disabled":true},{"key":"offset","value":"","description":"The older way to page. Use `cursor`.","disabled":true}]},"description":"Newest first, 25 to a page; pass `meta.next_cursor` back as `cursor`. `since` returns only opt-outs added from that time on, which suits a regular sync. Paging with `offset` (50 to a page by default, with `meta.total`) still works for now; new code should use the cursor."},"response":[]},{"name":"Add an opt-out","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/opt-outs","host":["{{baseUrl}}"],"path":["opt-outs"]},"body":{"mode":"raw","raw":"{\n  \"phone\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"Add an opt-out"},"response":[]},{"name":"Remove an opt-out","request":{"method":"DELETE","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/opt-outs/:phone","host":["{{baseUrl}}"],"path":["opt-outs",":phone"],"query":[{"key":"reason","value":"","description":"Instead of the body.","disabled":true}],"variable":[{"key":"phone","value":"","description":""}]},"body":{"mode":"raw","raw":"{\n  \"reason\": \"Asked in the shop to get offers again\"\n}","options":{"raw":{"language":"json"}}},"description":"Only when the person has asked to hear from you again. Give the reason as `{ \"reason\": \"...\" }` or `?reason=`; it is kept with who removed the number (see GET /opt-outs/removals). From the dashboard, only an owner or admin can do this."},"response":[]}]},{"name":"Sender names","description":"Alphanumeric senders (approval needed).","item":[{"name":"List sender names","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/sender-ids","host":["{{baseUrl}}"],"path":["sender-ids"]},"description":"List sender names"},"response":[]},{"name":"Ask for a sender name","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/sender-ids","host":["{{baseUrl}}"],"path":["sender-ids"]},"body":{"mode":"raw","raw":"{\n  \"value\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"The networks also need the business behind the name: send it with PUT /sender-ids/{id}/details."},"response":[]},{"name":"Withdraw a sender name","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/sender-ids/:id","host":["{{baseUrl}}"],"path":["sender-ids",":id"],"variable":[{"key":"id","value":"","description":"The sender name id."}]},"description":"Takes back a request, or a name you no longer want. Texts already sent under it are not affected."},"response":[]},{"name":"Get the business details behind a sender name","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/sender-ids/:id/details","host":["{{baseUrl}}"],"path":["sender-ids",":id","details"],"variable":[{"key":"id","value":"","description":"The sender name id."}]},"description":"Get the business details behind a sender name"},"response":[]},{"name":"Give the business details behind a sender name","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/sender-ids/:id/details","host":["{{baseUrl}}"],"path":["sender-ids",":id","details"],"variable":[{"key":"id","value":"","description":"The sender name id."}]},"body":{"mode":"raw","raw":"{\n  \"business_name\": \"\",\n  \"address\": \"\",\n  \"phone\": \"\",\n  \"rep_name\": \"\",\n  \"rep_role\": \"\",\n  \"rep_email\": \"\",\n  \"signature\": \"\",\n  \"authorise\": true\n}","options":{"raw":{"language":"json"}}},"description":"The networks clear a sender name only once they know who it belongs to. This saves the business details and signs a letter of authority in the representative's name, replacing anything given before.\n\n`signature` must repeat `rep_name`, and `authorise` must be true. Give a `website`, `evidence` or an evidence file. When `brand_owner` is `client`, include an `authorisation` file (the brand owner's permission letter or contract). Files are PDF, PNG or JPEG, up to 4 MB each and 5 per name, sent as base64."},"response":[]}]},{"name":"Webhooks","description":"Endpoints that receive events.","item":[{"name":"List webhooks","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/webhooks","host":["{{baseUrl}}"],"path":["webhooks"]},"description":"List webhooks"},"response":[]},{"name":"Create a webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/webhooks","host":["{{baseUrl}}"],"path":["webhooks"]},"body":{"mode":"raw","raw":"{\n  \"url\": \"https://example.com/connect/events\",\n  \"events\": [\n    \"message.delivered\",\n    \"message.received\"\n  ]\n}","options":{"raw":{"language":"json"}}},"description":"The response includes `secret`, shown only this once. One created with a test key is `test_only`: it receives events about test texts only, and test keys see no other webhooks."},"response":[]},{"name":"Get a webhook","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/webhooks/:id","host":["{{baseUrl}}"],"path":["webhooks",":id"],"variable":[{"key":"id","value":"","description":"The webhook id."}]},"description":"Get a webhook"},"response":[]},{"name":"Update a webhook","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/webhooks/:id","host":["{{baseUrl}}"],"path":["webhooks",":id"],"variable":[{"key":"id","value":"","description":"The webhook id."}]},"body":{"mode":"raw","raw":"{\n  \"url\": \"\",\n  \"events\": [],\n  \"description\": \"\",\n  \"enabled\": false,\n  \"rotate_secret\": false\n}","options":{"raw":{"language":"json"}}},"description":"`rotate_secret: true` issues a new secret, returned once. For the next 24 hours deliveries are signed with both secrets (see `previous_secret_expires_at`), so you can switch over without dropping an event."},"response":[]},{"name":"Delete a webhook","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/webhooks/:id","host":["{{baseUrl}}"],"path":["webhooks",":id"],"variable":[{"key":"id","value":"","description":"The webhook id."}]},"description":"Delete a webhook"},"response":[]},{"name":"Send a test event now","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/webhooks/:id/test","host":["{{baseUrl}}"],"path":["webhooks",":id","test"],"variable":[{"key":"id","value":"","description":"The webhook id."}]},"description":"Send a test event now"},"response":[]},{"name":"Recent deliveries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/webhooks/:id/deliveries","host":["{{baseUrl}}"],"path":["webhooks",":id","deliveries"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true}],"variable":[{"key":"id","value":"","description":"The webhook id."}]},"description":"Recent deliveries"},"response":[]},{"name":"Send a delivery again","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/webhooks/:id/deliveries/:delivery_id/retry","host":["{{baseUrl}}"],"path":["webhooks",":id","deliveries",":delivery_id","retry"],"variable":[{"key":"id","value":"","description":"The webhook id."},{"key":"delivery_id","value":"","description":"The delivery id (whd_...)."}]},"description":"Puts a failed (or still waiting) delivery back in the queue to go within a few seconds, with a fresh set of retries. Use it after fixing your endpoint, or after turning a switched-off webhook back on. The event id and `X-Connect-Delivery` stay the same, so your duplicate check still works."},"response":[]}]},{"name":"Account","description":"Balance and usage.","item":[{"name":"List dedicated numbers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/numbers","host":["{{baseUrl}}"],"path":["numbers"]},"description":"The UK mobile numbers dedicated to the account. Texts on the SIM route go from one of them and every reply to it belongs to the account. Each is rented monthly in credits (`rental_credits`, taken every 30 days from `rental_charged_at`). Ask for one, or release one, from the Numbers page in the dashboard."},"response":[]},{"name":"List the numbers you can send from","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/numbers/from","host":["{{baseUrl}}"],"path":["numbers","from"]},"description":"Every number the account can pass as `from` on POST /messages. A `sim` number is a SIM gateway: a text sent from it waits for that gateway while it is offline. An `aggregator` number is always available."},"response":[]},{"name":"Credit balance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/balance","host":["{{baseUrl}}"],"path":["balance"]},"description":"Credit balance"},"response":[]},{"name":"Totals for a period","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/stats/summary","host":["{{baseUrl}}"],"path":["stats","summary"],"query":[{"key":"days","value":"","description":"","disabled":true},{"key":"from","value":"","description":"","disabled":true},{"key":"to","value":"","description":"","disabled":true}]},"description":"Totals for a period"},"response":[]},{"name":"Daily counts for a period","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/stats/timeseries","host":["{{baseUrl}}"],"path":["stats","timeseries"],"query":[{"key":"days","value":"","description":"","disabled":true}]},"description":"Daily counts for a period"},"response":[]}]},{"name":"Custom fields","description":"Up to 20 extra fields on every contact, each text, date or number, usable as merge fields.","item":[{"name":"List custom fields","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/custom-fields","host":["{{baseUrl}}"],"path":["custom-fields"]},"description":"Oldest first; at most 20, so never paged. Keys contacts already held before the list existed are added as text fields the first time it is read."},"response":[]},{"name":"Add a custom field","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/custom-fields","host":["{{baseUrl}}"],"path":["custom-fields"]},"body":{"mode":"raw","raw":"{\n  \"label\": \"Birthday\",\n  \"type\": \"date\"\n}","options":{"raw":{"language":"json"}}},"description":"Up to 20 an account. The key is made from the label when left out (\"Renewal date\" becomes renewal_date). A contact sent through the API with a key that is not a field yet gets it added as a text field while there is room."},"response":[]},{"name":"Get a custom field","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/custom-fields/:id","host":["{{baseUrl}}"],"path":["custom-fields",":id"],"variable":[{"key":"id","value":"","description":"The custom field id."}]},"description":"Get a custom field"},"response":[]},{"name":"Rename a custom field","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/custom-fields/:id","host":["{{baseUrl}}"],"path":["custom-fields",":id"],"variable":[{"key":"id","value":"","description":"The custom field id."}]},"body":{"mode":"raw","raw":"{\n  \"label\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"Only the label changes. The key, which texts use, and the type stay as they are."},"response":[]},{"name":"Delete a custom field","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/custom-fields/:id","host":["{{baseUrl}}"],"path":["custom-fields",":id"],"variable":[{"key":"id","value":"","description":"The custom field id."}]},"description":"Removes the field and its value from every contact. Refused while a segment or reminder uses it."},"response":[]}]},{"name":"Segments","description":"Saved filters that work as a dynamic audience for campaigns and sends.","item":[{"name":"List segments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/segments","host":["{{baseUrl}}"],"path":["segments"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true}]},"description":"List segments"},"response":[]},{"name":"Create a segment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/segments","host":["{{baseUrl}}"],"path":["segments"]},"body":{"mode":"raw","raw":"{\n  \"name\": \"Birthdays this week\",\n  \"match\": \"all\",\n  \"conditions\": [\n    {\n      \"type\": \"field\",\n      \"field\": \"birthday\",\n      \"op\": \"within_days\",\n      \"days\": 7,\n      \"every_year\": true\n    },\n    {\n      \"type\": \"list\",\n      \"op\": \"in\",\n      \"list_id\": \"lst_01J9Z8X7W6V5T4S3R2Q1P0N9M7\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"description":"Create a segment"},"response":[]},{"name":"Preview conditions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/segments/preview","host":["{{baseUrl}}"],"path":["segments","preview"]},"body":{"mode":"raw","raw":"{\n  \"conditions\": []\n}","options":{"raw":{"language":"json"}}},"description":"Checks conditions without saving them: how many contacts they match now, and the ten newest of them."},"response":[]},{"name":"Get a segment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/segments/:id","host":["{{baseUrl}}"],"path":["segments",":id"],"variable":[{"key":"id","value":"","description":"The segment id."}]},"description":"Get a segment"},"response":[]},{"name":"Change a segment","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/segments/:id","host":["{{baseUrl}}"],"path":["segments",":id"],"variable":[{"key":"id","value":"","description":"The segment id."}]},"body":{"mode":"raw","raw":"{\n  \"name\": \"\",\n  \"match\": \"all\",\n  \"conditions\": []\n}","options":{"raw":{"language":"json"}}},"description":"Change a segment"},"response":[]},{"name":"Delete a segment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/segments/:id","host":["{{baseUrl}}"],"path":["segments",":id"],"variable":[{"key":"id","value":"","description":"The segment id."}]},"description":"Refused while a recurring campaign that has not ended, or a reminder, sends to it. A draft campaign just loses its segment."},"response":[]},{"name":"Count a segment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/segments/:id/count","host":["{{baseUrl}}"],"path":["segments",":id","count"],"variable":[{"key":"id","value":"","description":"The segment id."}]},"description":"How many contacts are in it right now."},"response":[]},{"name":"A segment's contacts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/segments/:id/contacts","host":["{{baseUrl}}"],"path":["segments",":id","contacts"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true}],"variable":[{"key":"id","value":"","description":"The segment id."}]},"description":"As it stands now, newest first."},"response":[]}]},{"name":"Recurring campaigns","description":"A campaign that sends again weekly or monthly, one run per slot.","item":[{"name":"List recurring campaigns","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/campaign-series","host":["{{baseUrl}}"],"path":["campaign-series"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true},{"key":"status","value":"","description":"Comma-separated, for example active,paused.","disabled":true}]},"description":"GET /campaigns?series_id= lists the runs of one."},"response":[]},{"name":"Start a recurring campaign","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/campaign-series","host":["{{baseUrl}}"],"path":["campaign-series"]},"body":{"mode":"raw","raw":"{\n  \"name\": \"Friday specials\",\n  \"body\": \"This weekend at the Crown: {first_name}, show this text for a free dessert.\",\n  \"list_id\": \"lst_01J9Z8X7W6V5T4S3R2Q1P0N9M7\",\n  \"repeat\": \"weekly\",\n  \"weekdays\": [\n    5\n  ],\n  \"time\": \"11:00\"\n}","options":{"raw":{"language":"json"}}},"description":"The first run goes at the first slot after now."},"response":[]},{"name":"Get a recurring campaign","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/campaign-series/:id","host":["{{baseUrl}}"],"path":["campaign-series",":id"],"variable":[{"key":"id","value":"","description":"The recurring campaign id."}]},"description":"Get a recurring campaign"},"response":[]},{"name":"Change a recurring campaign","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/campaign-series/:id","host":["{{baseUrl}}"],"path":["campaign-series",":id"],"variable":[{"key":"id","value":"","description":"The recurring campaign id."}]},"body":{"mode":"raw","raw":"{\n  \"name\": \"\",\n  \"body\": \"\",\n  \"list_id\": \"\",\n  \"segment_id\": \"\",\n  \"sender\": \"\",\n  \"from\": \"\",\n  \"append_opt_out\": false,\n  \"track_links\": false,\n  \"repeat\": \"weekly\",\n  \"weekdays\": [],\n  \"month_day\": 1,\n  \"time\": \"\",\n  \"ends_on\": \"\",\n  \"max_runs\": 1\n}","options":{"raw":{"language":"json"}}},"description":"For one that has not ended. A new schedule counts from now; runs already made keep their own text."},"response":[]},{"name":"Pause","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/campaign-series/:id/pause","host":["{{baseUrl}}"],"path":["campaign-series",":id","pause"],"variable":[{"key":"id","value":"","description":"The recurring campaign id."}]},"description":"No runs are made until it is resumed."},"response":[]},{"name":"Resume","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/campaign-series/:id/resume","host":["{{baseUrl}}"],"path":["campaign-series",":id","resume"],"variable":[{"key":"id","value":"","description":"The recurring campaign id."}]},"description":"Carries on from the next slot after now. Runs missed while it was paused are not sent."},"response":[]},{"name":"Stop for good","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/campaign-series/:id/stop","host":["{{baseUrl}}"],"path":["campaign-series",":id","stop"],"variable":[{"key":"id","value":"","description":"The recurring campaign id."}]},"description":"Runs already made carry on; cancel one with POST /campaigns/{id}/cancel."},"response":[]}]},{"name":"Reminders","description":"Texts tied to a date on each contact, such as a birthday or renewal date.","item":[{"name":"List reminders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/automations","host":["{{baseUrl}}"],"path":["automations"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true}]},"description":"List reminders"},"response":[]},{"name":"Create a reminder","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/automations","host":["{{baseUrl}}"],"path":["automations"]},"body":{"mode":"raw","raw":"{\n  \"name\": \"Birthday treat\",\n  \"body\": \"Happy birthday {first_name}! Your free coffee is waiting this week.\",\n  \"field_key\": \"birthday\",\n  \"direction\": \"on\",\n  \"time\": \"10:00\",\n  \"every_year\": true,\n  \"audience\": \"all\"\n}","options":{"raw":{"language":"json"}}},"description":"One made after today's time first runs tomorrow."},"response":[]},{"name":"Get a reminder","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/automations/:id","host":["{{baseUrl}}"],"path":["automations",":id"],"variable":[{"key":"id","value":"","description":"The reminder id."}]},"description":"Get a reminder"},"response":[]},{"name":"Change a reminder","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/automations/:id","host":["{{baseUrl}}"],"path":["automations",":id"],"variable":[{"key":"id","value":"","description":"The reminder id."}]},"body":{"mode":"raw","raw":"{\n  \"name\": \"\",\n  \"body\": \"\",\n  \"template_id\": \"\",\n  \"field_key\": \"\",\n  \"direction\": \"before\",\n  \"offset_days\": 0,\n  \"time\": \"\",\n  \"every_year\": false,\n  \"audience\": \"all\",\n  \"list_id\": \"\",\n  \"segment_id\": \"\",\n  \"sender\": \"\",\n  \"from\": \"\",\n  \"append_opt_out\": false,\n  \"enabled\": false\n}","options":{"raw":{"language":"json"}}},"description":"Change a reminder"},"response":[]},{"name":"Delete a reminder","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/automations/:id","host":["{{baseUrl}}"],"path":["automations",":id"],"variable":[{"key":"id","value":"","description":"The reminder id."}]},"description":"Its log goes too; the texts it sent stay in the message log."},"response":[]},{"name":"Next run","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/automations/:id/preview","host":["{{baseUrl}}"],"path":["automations",":id","preview"],"variable":[{"key":"id","value":"","description":"The reminder id."}]},"description":"When the reminder runs next and how many contacts it would text then, as things stand now."},"response":[]},{"name":"A reminder's log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/automations/:id/sends","host":["{{baseUrl}}"],"path":["automations",":id","sends"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true}],"variable":[{"key":"id","value":"","description":"The reminder id."}]},"description":"Who it texted, or skipped and why, and for which date, newest first."},"response":[]}]},{"name":"Keywords","description":"Words people text in for an automatic reply and a list.","item":[{"name":"List keywords","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/keywords","host":["{{baseUrl}}"],"path":["keywords"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true}]},"description":"List keywords"},"response":[]},{"name":"Create a keyword","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/keywords","host":["{{baseUrl}}"],"path":["keywords"]},"body":{"mode":"raw","raw":"{\n  \"keyword\": \"JOIN\",\n  \"reply\": \"Thanks, you are on the list.\",\n  \"add_to_list_id\": \"lst_01J9Z8X7W6V5T4S3R2Q1P0N9M2\"\n}","options":{"raw":{"language":"json"}}},"description":"A keyword is matched against the first word of an inbound text, ignoring case and punctuation. When it matches, the sender becomes a contact, is added to `add_to_list_id` when set, and gets `reply` as a text from your number (one credit per part, nothing to an opted-out number). STOP, STOPALL, UNSUBSCRIBE, CANCEL, END, QUIT, OPTOUT, START and UNSTOP are reserved and refused with `reserved_keyword`. On a shared number a keyword works for people you texted in the last 30 days; on a dedicated number it works for anyone."},"response":[]},{"name":"Get a keyword","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/keywords/:id","host":["{{baseUrl}}"],"path":["keywords",":id"],"variable":[{"key":"id","value":"","description":"The keyword id."}]},"description":"Get a keyword"},"response":[]},{"name":"Edit a keyword","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/keywords/:id","host":["{{baseUrl}}"],"path":["keywords",":id"],"variable":[{"key":"id","value":"","description":"The keyword id."}]},"body":{"mode":"raw","raw":"{\n  \"keyword\": \"\"\n}","options":{"raw":{"language":"json"}}},"description":"Edit a keyword"},"response":[]},{"name":"Delete a keyword","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/keywords/:id","host":["{{baseUrl}}"],"path":["keywords",":id"],"variable":[{"key":"id","value":"","description":"The keyword id."}]},"description":"Delete a keyword"},"response":[]}]},{"name":"Links","description":"Short tracked links and their clicks.","item":[{"name":"List tracked links","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/links","host":["{{baseUrl}}"],"path":["links"],"query":[{"key":"limit","value":"","description":"Items per page, 1 to 100 (default 25).","disabled":true},{"key":"cursor","value":"","description":"The `meta.next_cursor` of the previous page.","disabled":true},{"key":"campaign_id","value":"","description":"","disabled":true},{"key":"message_id","value":"","description":"","disabled":true}]},"description":"One row per URL per recipient, newest first. Filter by campaign or message."},"response":[]},{"name":"Get a tracked link","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/links/:id","host":["{{baseUrl}}"],"path":["links",":id"],"variable":[{"key":"id","value":"","description":"The link id."}]},"description":"Get a tracked link"},"response":[]}]},{"name":"Batches","description":"One send request and everything in it.","item":[{"name":"Get a batch","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/batches/:id","host":["{{baseUrl}}"],"path":["batches",":id"],"variable":[{"key":"id","value":"","description":"The batch id."}]},"description":"A batch is one send request: POST /messages, a bulk send or a campaign launch (every message carries its `batch_id`). `counts` gives its texts by status. A send of more than 1,000 recipients made with `Prefer: respond-async` is `processing` until it has been sent, then `processed`, or `failed` with the reason in `error` (for example `insufficient_credit`), in which case nothing was sent or charged."},"response":[]},{"name":"Cancel everything unsent in a batch","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/batches/:id/cancel","host":["{{baseUrl}}"],"path":["batches",":id","cancel"],"variable":[{"key":"id","value":"","description":"The batch id."}]},"description":"Cancels every text in the batch that has not left yet (awaiting review, scheduled or queued), refunds it and raises `message.cancelled` for each. Texts already on their way finish as normal. A background send still `processing` is stopped before anything is charged. A campaign launch is cancelled with POST /campaigns/{id}/cancel instead (`campaign_send`)."},"response":[]}]},{"name":"Data and privacy","description":"Erasing a person from your account.","item":[{"name":"Erase a number from your account","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/erasures","host":["{{baseUrl}}"],"path":["erasures"]},"body":{"mode":"raw","raw":"{\n  \"phone\": \"07412 000001\"\n}","options":{"raw":{"language":"json"}}},"description":"For a person who has asked you to delete their data. In one step: texts not yet sent to the number are cancelled and refunded (error code `number_erased`), its contact is deleted, every text to or from it has its body removed and the number replaced by a stand-in, its tracked link clicks are deleted, and earlier webhook deliveries that name it are deleted. Texts already on their way are left to finish (`messages_in_flight`); erase again once they have.\n\nIf the number had opted out it stays blocked: we keep a keyed hash of it, not the number, so your account still refuses to text it. Take it off with DELETE /opt-outs/{phone} if the person later asks to hear from you. Erasing cannot be undone. Owners and admins only from the dashboard; live keys only."},"response":[]}]},{"name":"Reference","description":"This document and the Postman collection, no key needed.","item":[{"name":"This OpenAPI document","request":{"method":"GET","auth":{"type":"noauth"},"header":[],"url":{"raw":"{{baseUrl}}/openapi.json","host":["{{baseUrl}}"],"path":["openapi.json"]},"description":"This OpenAPI document"},"response":[]},{"name":"A Postman collection of the API","request":{"method":"GET","auth":{"type":"noauth"},"header":[],"url":{"raw":"{{baseUrl}}/postman.json","host":["{{baseUrl}}"],"path":["postman.json"]},"description":"Built from this document. Import it into Postman, then set the collection variables `baseUrl` and `api_key`."},"response":[]}]}]}