The API is included in the plan. The account owner creates keys in the developer settings. For a test account, email hello@storebay.co.uk.

Developers
Comms

Create a message

Queues an email or SMS to a contact. Delivery runs asynchronously through the dispatcher (Resend / Bird).

POST
/messages

Queues an email or SMS to a contact. Delivery runs asynchronously through the dispatcher (Resend / Bird).

Authorization

AuthorizationBearer <token>

Present an API key (sb_live_… / sb_test_…), an OAuth2 access token, or a static token as a Bearer credential. The operator is implied by the credential; it is never in the path. Only a SHA-256 hash of an API key is stored server-side.

In: header

Header Parameters

Idempotency-Key?string

A unique key that makes this mutation safe to retry. Repeats replay the stored response; reuse with a different body returns 409 idempotency_conflict.

Lengthlength <= 255

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/messages" \  -H "Content-Type: application/json" \  -d '{    "channel": "email"  }'
{  "data": {    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",    "object": "message",    "contact_id": "f245e2a3-e141-4d41-912c-b1c1f5bd5598",    "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",    "channel": "email",    "provider": "resend",    "direction": "outbound",    "to_address": "string",    "from_address": "string",    "subject": "string",    "body": "string",    "status": "queued",    "provider_message_ref": "string",    "blocked_reason": "operator_disabled",    "sent_at": "2019-08-24T14:15:22Z",    "delivered_at": "2019-08-24T14:15:22Z",    "created_at": "2019-08-24T14:15:22Z",    "updated_at": "2019-08-24T14:15:22Z"  }}
{  "error": {    "code": "unauthorized",    "message": "Missing or invalid credential."  }}
{  "error": {    "code": "insufficient_scope",    "message": "The credential lacks a scope required by this endpoint."  }}
{  "error": {    "code": "validation_error",    "message": "One or more fields are invalid.",    "details": [      {        "field": "email",        "issue": "must be a valid email address"      }    ]  }}
{  "error": {    "code": "rate_limited",    "message": "Rate limit exceeded. Retry after 7s."  }}
{  "error": {    "code": "validation_error",    "message": "string",    "details": [      {        "field": "string",        "issue": "string"      }    ]  }}

Update a subscription PATCH

Only the fields supplied are changed. On an active or past-due subscription, next_billing_date and anchor_day are refused with 409 subscription_renewal_date_endpoint, even when they carry the value the subscription already has: the renewal date moves through POST /subscriptions/{id}/renewal-date, which bills the days between the old and new dates. On a pending subscription, a next_billing_date on or before the end of a period already invoiced is refused with 409 conflict, and so is a new next_billing_date while cover or a repeating charge starts on the current next_billing_date or on the agreement's move_in_date: move the agreement's move_in_date instead, which moves them. While a renewal date change is pending (pending_renewal_change is set), a change to billing_interval or interval_count is refused with 409 conflict until the change is cancelled, because the pending change was worked out for the current cadence. On a subscription with no licence fee (one with no agreement, which bills only its repeating charges) a change to amount_minor is refused with 409 conflict: its price is the sum of those charges. A new billing_interval or interval_count re-prices every repeating charge and every cover the subscription bills from its next invoice, each converted afresh from the price it was converted from (a charge's own price, a cover's premium) and never from its old amount per period; amount_minor moves by what the next invoice then bills. The licence fee is not re-priced: an amount_minor sent with the new period moves it by the difference from the current amount_minor, and the re-pricing lands on top. A charge with no price of its own on a subscription billed every two or more intervals, or one that can't be priced for the new period, refuses the whole change with 409 conflict, and nothing is written. An amount_minor equal to the current one is no change. With expected_amount_minor, a change is refused with 409 conflict when the subscription's amount_minor is no longer that figure.

Retrieve a message GET

Next Page