Home

Nitrosend API

v1.1.6
Base URLs
https://api.nitrosend.comProduction
http://localhost:8000Local development

Multi-channel marketing automation API. Send email campaigns, build automation flows, manage contacts and segments, track events, and configure your Brand Kit — all via a single REST API.

Authentication

All /v1/my/* endpoints require authentication via Bearer token. Three token types are accepted:

  1. API Key — Authorization: Bearer nskey_live_...
  2. JWT — Authorization: Bearer <jwt> (obtained from POST /v1/login)
  3. Shopify ID token — supplied by App Bridge for an installed embedded app

Pagination

Paginated endpoints return these headers:

  • X-Total-Count — total records
  • X-Total-Pages — total pages
  • X-Page-Number — current page
  • X-Next-Page — next page (omitted on last page)
  • X-Prev-Page — previous page (omitted on first page)

Use page and limit (or per) query params to control pagination. Maximum limit is 100, default is 30.

Error Responses

All errors return a consistent JSON shape:

{
  "code": 422,
  "message": "Description of error",
  "error": true,
  "validation_errors": { "field": ["error message"] }
}

The validation_errors key is only present on 422 responses.

Authentication

BearerAuthhttp

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Scheme: bearer

PartnerProvisioningCredentialhttp

Manager-account provisioning credential revealed once at issuance.

Scheme: bearer (nspk_live)

ManagementCredentialhttp

One-time-revealed operator_v1 credential pinned to one active management grant and Brand.

Scheme: bearer (nsmc_live)

Auth

Login, logout, and registration

Create a new account

POST
https://api.nitrosend.com/v1/signup

Body

application/json
userobjectrequired
Show child attributes
first_namestring
last_namestring
emailstring<email>required
mobilestring
invite_tokenstring | null
passwordstring<password>required
password_confirmationstring<password>

Response

201CreatedUser

Account created

422Unprocessable EntityError & object

Validation failed

Create a new account
curl -X POST 'https://api.nitrosend.com/v1/signup' \
  -H 'Content-Type: application/json' \
  -d '{
    "user": {
      "first_name": "string",
      "last_name": "string",
      "email": "user@example.com",
      "mobile": "string",
      "invite_token": "string",
      "password": "********",
      "password_confirmation": "********"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/signup', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "user": {
        "first_name": "string",
        "last_name": "string",
        "email": "user@example.com",
        "mobile": "string",
        "invite_token": "string",
        "password": "********",
        "password_confirmation": "********"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "user": {
    "first_name": "string",
    "last_name": "string",
    "email": "user@example.com",
    "mobile": "string",
    "invite_token": "string",
    "password": "********",
    "password_confirmation": "********"
  }
}

response = requests.post('https://api.nitrosend.com/v1/signup', json=payload)
data = response.json()
Request Body
{
  "user": {
    "first_name": "string",
    "last_name": "string",
    "email": "user@example.com",
    "mobile": "string",
    "invite_token": "string",
    "password": "********",
    "password_confirmation": "********"
  }
}
{
  "id": 0,
  "first_name": "string",
  "last_name": "string",
  "email": "user@example.com",
  "mobile": "string",
  "country_code": "string",
  "time_zone": "string",
  "admin": true,
  "ui_login_count": 0,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Sign in and receive a JWT

POST
https://api.nitrosend.com/v1/login

Body

application/json
userobjectrequired
Show child attributes
emailstring<email>required
passwordstring<password>required

Response

200OKUser

Signed in

401UnauthorizedError

Not authenticated

Sign in and receive a JWT
curl -X POST 'https://api.nitrosend.com/v1/login' \
  -H 'Content-Type: application/json' \
  -d '{
    "user": {
      "email": "user@example.com",
      "password": "********"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "user": {
        "email": "user@example.com",
        "password": "********"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "user": {
    "email": "user@example.com",
    "password": "********"
  }
}

response = requests.post('https://api.nitrosend.com/v1/login', json=payload)
data = response.json()
Request Body
{
  "user": {
    "email": "user@example.com",
    "password": "********"
  }
}
{
  "id": 0,
  "first_name": "string",
  "last_name": "string",
  "email": "user@example.com",
  "mobile": "string",
  "country_code": "string",
  "time_zone": "string",
  "admin": true,
  "ui_login_count": 0,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Sign out and revoke JWT

DELETE
https://api.nitrosend.com/v1/logout

Response

204No Content

Signed out

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Sign out and revoke JWT
curl -X DELETE 'https://api.nitrosend.com/v1/logout'
const response = await fetch('https://api.nitrosend.com/v1/logout', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/logout')
data = response.json()

Get OAuth popup context

GET
https://api.nitrosend.com/v1/oauth/me

Returns the account-selection and subscription context used by the /oauth/connect popup. This endpoint accepts the normal Bearer JWT and, for popup resume flows, the authenticated browser session cookie established by Devise/OmniAuth.

Response

200OKOAuthPopupContext

Popup context

401UnauthorizedError

Not authenticated

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get OAuth popup context
curl -X GET 'https://api.nitrosend.com/v1/oauth/me'
const response = await fetch('https://api.nitrosend.com/v1/oauth/me', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/oauth/me')
data = response.json()
{
  "accounts": [
    {
      "id": 0,
      "name": "string",
      "access": {
        "source": "owner",
        "delegated": true,
        "manager_account_id": 0,
        "manager_account_name": "string",
        "management_grant_id": 0,
        "permission_set": "operator_v1",
        "credential_type": "management"
      },
      "can_manage": true,
      "needs_subscribe": true
    }
  ],
  "plans": [
    {
      "id": 0,
      "name": "string",
      "slug": "string",
      "base_price_cents": 0,
      "interval": "string"
    }
  ],
  "stripe_publishable_key": "string"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Subscribe the selected OAuth popup account

POST
https://api.nitrosend.com/v1/oauth/subscribe

Finalizes plan selection for the /oauth/connect popup before the browser returns to the Doorkeeper consent screen. This endpoint accepts the normal Bearer JWT and, for popup resume flows, the authenticated browser session cookie established by Devise/OmniAuth.

Body

application/json
plan_idintegerrequired
account_idinteger | null
stripe_tokenstring | null

Response

200OKOAuthPopupSubscribeResponse

Popup can continue to consent

401UnauthorizedError

Not authenticated

422Unprocessable Entityobject

Account or plan selection failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Subscribe the selected OAuth popup account
curl -X POST 'https://api.nitrosend.com/v1/oauth/subscribe' \
  -H 'Content-Type: application/json' \
  -d '{
    "plan_id": 0,
    "account_id": 0,
    "stripe_token": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/oauth/subscribe', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "plan_id": 0,
      "account_id": 0,
      "stripe_token": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "plan_id": 0,
  "account_id": 0,
  "stripe_token": "string"
}

response = requests.post('https://api.nitrosend.com/v1/oauth/subscribe', json=payload)
data = response.json()
Request Body
{
  "plan_id": 0,
  "account_id": 0,
  "stripe_token": "string"
}
{
  "next_step": "consent"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "error": "string"
}

Create a CSRF-safe OAuth provider launch URL

POST
https://api.nitrosend.com/v1/oauth/launch

Mints a short-lived launch URL for Google or GitHub sign-in. The frontend follows the returned API-origin launch page, which renders the real POST form to /auth/:provider with a valid Rails authenticity token. This preserves OmniAuth's POST-only request phase and CSRF protection for both the app popup flow and the /oauth/connect agent popup flow.

Body

application/json
providerstringgoogle_oauth2githubrequired
auth_intentstringappagentapp
auth_stepstringloginsignuplogin
resume_urlstring<uri> | null

Required when auth_intent=agent; must point to the frontend /oauth/connect route.

Response

200OKOAuthLaunchResponse

Launch URL created

400Bad Requestobject

Invalid provider or resume URL

Create a CSRF-safe OAuth provider launch URL
curl -X POST 'https://api.nitrosend.com/v1/oauth/launch' \
  -H 'Content-Type: application/json' \
  -d '{
    "provider": "google_oauth2",
    "auth_intent": "app",
    "auth_step": "login",
    "resume_url": "https://example.com"
  }'
const response = await fetch('https://api.nitrosend.com/v1/oauth/launch', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "provider": "google_oauth2",
      "auth_intent": "app",
      "auth_step": "login",
      "resume_url": "https://example.com"
    }),
});

const data = await response.json();
import requests

payload = {
  "provider": "google_oauth2",
  "auth_intent": "app",
  "auth_step": "login",
  "resume_url": "https://example.com"
}

response = requests.post('https://api.nitrosend.com/v1/oauth/launch', json=payload)
data = response.json()
Request Body
{
  "provider": "google_oauth2",
  "auth_intent": "app",
  "auth_step": "login",
  "resume_url": "https://example.com"
}
{
  "launch_url": "https://example.com"
}
{
  "error": "string"
}

User

Current user profile

Get current user profile

GET
https://api.nitrosend.com/v1/my/user

Response

200OKUser

User profile

401UnauthorizedError

Not authenticated

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get current user profile
curl -X GET 'https://api.nitrosend.com/v1/my/user'
const response = await fetch('https://api.nitrosend.com/v1/my/user', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/user')
data = response.json()
{
  "id": 0,
  "first_name": "string",
  "last_name": "string",
  "email": "user@example.com",
  "mobile": "string",
  "country_code": "string",
  "time_zone": "string",
  "admin": true,
  "ui_login_count": 0,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Update current user profile

PATCH
https://api.nitrosend.com/v1/my/user

Body

application/json
first_namestring
last_namestring
emailstring | Array<string>
mobilestring
time_zonestring | null

Response

200OKUser

Updated user

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update current user profile
curl -X PATCH 'https://api.nitrosend.com/v1/my/user' \
  -H 'Content-Type: application/json' \
  -d '{
    "first_name": "string",
    "last_name": "string",
    "email": "user@example.com",
    "mobile": "string",
    "time_zone": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/user', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "first_name": "string",
      "last_name": "string",
      "email": "user@example.com",
      "mobile": "string",
      "time_zone": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "first_name": "string",
  "last_name": "string",
  "email": "user@example.com",
  "mobile": "string",
  "time_zone": "string"
}

response = requests.patch('https://api.nitrosend.com/v1/my/user', json=payload)
data = response.json()
Request Body
{
  "first_name": "string",
  "last_name": "string",
  "email": "user@example.com",
  "mobile": "string",
  "time_zone": "string"
}
{
  "id": 0,
  "first_name": "string",
  "last_name": "string",
  "email": "user@example.com",
  "mobile": "string",
  "country_code": "string",
  "time_zone": "string",
  "admin": true,
  "ui_login_count": 0,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get current impersonation status

GET
https://api.nitrosend.com/v1/my/impersonation

Response

200OKImpersonationStatus

Current impersonation state

401UnauthorizedError

Not authenticated

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get current impersonation status
curl -X GET 'https://api.nitrosend.com/v1/my/impersonation'
const response = await fetch('https://api.nitrosend.com/v1/my/impersonation', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/impersonation')
data = response.json()
{
  "impersonating": true,
  "impersonator": {
    "id": 0,
    "email": "user@example.com",
    "name": "string"
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Revoke the active impersonation session

DELETE
https://api.nitrosend.com/v1/my/impersonation

Response

200OKImpersonationExit

Impersonation session revoked

401UnauthorizedError

Not authenticated

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Revoke the active impersonation session
curl -X DELETE 'https://api.nitrosend.com/v1/my/impersonation'
const response = await fetch('https://api.nitrosend.com/v1/my/impersonation', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/impersonation')
data = response.json()
{
  "redirect_url": "https://api.nitrosend.com/adm"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Account

Account settings and configuration

Get account details

GET
https://api.nitrosend.com/v1/my/account

Response

200OKAccount

Account with billing. Brands are listed by GET /v1/my/brands.

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get account details
curl -X GET 'https://api.nitrosend.com/v1/my/account'
const response = await fetch('https://api.nitrosend.com/v1/my/account', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/account')
data = response.json()
200
{
  "id": 0,
  "name": "string",
  "avatar": "string",
  "banner": "string",
  "commercial_tier": "unsubscribed",
  "safe_mode_enabled": true,
  "access": {
    "source": "owner",
    "delegated": true,
    "manager_account_id": 0,
    "manager_account_name": "string",
    "management_grant_id": 0,
    "permission_set": "operator_v1",
    "credential_type": "management"
  },
  "billing": {
    "access_policy": "free_allowed",
    "plan_name": "string",
    "plan": {
      "id": 0,
      "name": "string",
      "active": true,
      "probation_recipient_cap_24h": 0,
      "standard_recipient_cap_24h": 0,
      "trusted_recipient_cap_24h": 0,
      "entitlements": {
        "agent_inbox": {
          "enabled": true,
          "max_inboxes": 0,
          "inbound_messages_included": 0,
          "inbound_messages_metered": true,
          "inbound_message_overage_rate_cents": "string",
          "max_inbound_domains": 0,
          "max_apex_domains": 0,
          "apex_mx": true,
          "legacy_forwarding": true,
          "catch_all": true,
          "retention_days": 0,
          "advanced_queue_controls": true
        }
      }
    },
    "spend_cap_monthly_cents": 0,
    "comped": true,
    "overage": {},
    "entitlements": {
      "agent_inbox": {
        "enabled": true,
        "max_inboxes": 0,
        "inbound_messages_included": 0,
        "inbound_messages_metered": true,
        "inbound_message_overage_rate_cents": "string",
        "max_inbound_domains": 0,
        "max_apex_domains": 0,
        "apex_mx": true,
        "legacy_forwarding": true,
        "catch_all": true,
        "retention_days": 0,
        "advanced_queue_controls": true
      }
    },
    "resources": {
      "email": {
        "used": 0,
        "allowance": 0,
        "remaining": 0,
        "overage_rate": 0,
        "mode": "budget",
        "budget": 0,
        "budget_used": 0
      },
      "sms": {
        "used": 0,
        "allowance": 0,
        "remaining": 0,
        "overage_rate": 0,
        "mode": "budget",
        "budget": 0,
        "budget_used": 0
      },
      "ai": {
        "used": 0,
        "allowance": 0,
        "remaining": 0,
        "overage_rate": 0,
        "mode": "budget",
        "budget": 0,
        "budget_used": 0
      }
    },
    "funding": {},
    "provider_route": {},
    "brands": {
      "used": 0,
      "limit": 0,
      "remaining": 0,
      "unlimited": true,
      "can_create": true
    },
    "lifetime": {
      "email_sent": 0,
      "sms_sent": 0,
      "ai_used": 0
    }
  },
  "team": {
    "seat_limit": 0,
    "seat_count": 0,
    "member_count": 0,
    "invite_count": 0,
    "current_role": "string",
    "can_manage_team": true
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

Update account settings

PATCH
https://api.nitrosend.com/v1/my/account

Body

application/json
namestring
avatarstring

Signed blob ID

bannerstring

Signed blob ID

Response

200OKAccount

Updated account

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update account settings
curl -X PATCH 'https://api.nitrosend.com/v1/my/account' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string",
    "avatar": "string",
    "banner": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/account', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string",
      "avatar": "string",
      "banner": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string",
  "avatar": "string",
  "banner": "string"
}

response = requests.patch('https://api.nitrosend.com/v1/my/account', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "avatar": "string",
  "banner": "string"
}
{
  "id": 0,
  "name": "string",
  "avatar": "string",
  "banner": "string",
  "commercial_tier": "unsubscribed",
  "safe_mode_enabled": true,
  "access": {
    "source": "owner",
    "delegated": true,
    "manager_account_id": 0,
    "manager_account_name": "string",
    "management_grant_id": 0,
    "permission_set": "operator_v1",
    "credential_type": "management"
  },
  "billing": {
    "access_policy": "free_allowed",
    "plan_name": "string",
    "plan": {
      "id": 0,
      "name": "string",
      "active": true,
      "probation_recipient_cap_24h": 0,
      "standard_recipient_cap_24h": 0,
      "trusted_recipient_cap_24h": 0,
      "entitlements": {
        "agent_inbox": {
          "enabled": true,
          "max_inboxes": 0,
          "inbound_messages_included": 0,
          "inbound_messages_metered": true,
          "inbound_message_overage_rate_cents": "string",
          "max_inbound_domains": 0,
          "max_apex_domains": 0,
          "apex_mx": true,
          "legacy_forwarding": true,
          "catch_all": true,
          "retention_days": 0,
          "advanced_queue_controls": true
        }
      }
    },
    "spend_cap_monthly_cents": 0,
    "comped": true,
    "overage": {},
    "entitlements": {
      "agent_inbox": {
        "enabled": true,
        "max_inboxes": 0,
        "inbound_messages_included": 0,
        "inbound_messages_metered": true,
        "inbound_message_overage_rate_cents": "string",
        "max_inbound_domains": 0,
        "max_apex_domains": 0,
        "apex_mx": true,
        "legacy_forwarding": true,
        "catch_all": true,
        "retention_days": 0,
        "advanced_queue_controls": true
      }
    },
    "resources": {
      "email": {
        "used": 0,
        "allowance": 0,
        "remaining": 0,
        "overage_rate": 0,
        "mode": "budget",
        "budget": 0,
        "budget_used": 0
      },
      "sms": {
        "used": 0,
        "allowance": 0,
        "remaining": 0,
        "overage_rate": 0,
        "mode": "budget",
        "budget": 0,
        "budget_used": 0
      },
      "ai": {
        "used": 0,
        "allowance": 0,
        "remaining": 0,
        "overage_rate": 0,
        "mode": "budget",
        "budget": 0,
        "budget_used": 0
      }
    },
    "funding": {},
    "provider_route": {},
    "brands": {
      "used": 0,
      "limit": 0,
      "remaining": 0,
      "unlimited": true,
      "can_create": true
    },
    "lifetime": {
      "email_sent": 0,
      "sms_sent": 0,
      "ai_used": 0
    }
  },
  "team": {
    "seat_limit": 0,
    "seat_count": 0,
    "member_count": 0,
    "invite_count": 0,
    "current_role": "string",
    "can_manage_team": true
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

List accessible accounts (paginated)

GET
https://api.nitrosend.com/v1/my/accounts

Parameters

pageinteger1query
perinteger<= 100100query

Response

200OKArray<Account>

Accessible accounts

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List accessible accounts (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/accounts'
const response = await fetch('https://api.nitrosend.com/v1/my/accounts', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/accounts')
data = response.json()
200
[
  {
    "id": 0,
    "name": "string",
    "avatar": "string",
    "banner": "string",
    "commercial_tier": "unsubscribed",
    "safe_mode_enabled": true,
    "access": {
      "source": "owner",
      "delegated": true,
      "manager_account_id": 0,
      "manager_account_name": "string",
      "management_grant_id": 0,
      "permission_set": "operator_v1",
      "credential_type": "management"
    },
    "billing": {
      "access_policy": "free_allowed",
      "plan_name": "string",
      "plan": {
        "id": 0,
        "name": "string",
        "active": true,
        "probation_recipient_cap_24h": 0,
        "standard_recipient_cap_24h": 0,
        "trusted_recipient_cap_24h": 0,
        "entitlements": {
          "agent_inbox": {
            "enabled": true,
            "max_inboxes": 0,
            "inbound_messages_included": 0,
            "inbound_messages_metered": true,
            "inbound_message_overage_rate_cents": "string",
            "max_inbound_domains": 0,
            "max_apex_domains": 0,
            "apex_mx": true,
            "legacy_forwarding": true,
            "catch_all": true,
            "retention_days": 0,
            "advanced_queue_controls": true
          }
        }
      },
      "spend_cap_monthly_cents": 0,
      "comped": true,
      "overage": {},
      "entitlements": {
        "agent_inbox": {
          "enabled": true,
          "max_inboxes": 0,
          "inbound_messages_included": 0,
          "inbound_messages_metered": true,
          "inbound_message_overage_rate_cents": "string",
          "max_inbound_domains": 0,
          "max_apex_domains": 0,
          "apex_mx": true,
          "legacy_forwarding": true,
          "catch_all": true,
          "retention_days": 0,
          "advanced_queue_controls": true
        }
      },
      "resources": {
        "email": {
          "used": 0,
          "allowance": 0,
          "remaining": 0,
          "overage_rate": 0,
          "mode": "budget",
          "budget": 0,
          "budget_used": 0
        },
        "sms": {
          "used": 0,
          "allowance": 0,
          "remaining": 0,
          "overage_rate": 0,
          "mode": "budget",
          "budget": 0,
          "budget_used": 0
        },
        "ai": {
          "used": 0,
          "allowance": 0,
          "remaining": 0,
          "overage_rate": 0,
          "mode": "budget",
          "budget": 0,
          "budget_used": 0
        }
      },
      "funding": {},
      "provider_route": {},
      "brands": {
        "used": 0,
        "limit": 0,
        "remaining": 0,
        "unlimited": true,
        "can_create": true
      },
      "lifetime": {
        "email_sent": 0,
        "sms_sent": 0,
        "ai_used": 0
      }
    },
    "team": {
      "seat_limit": 0,
      "seat_count": 0,
      "member_count": 0,
      "invite_count": 0,
      "current_role": "string",
      "can_manage_team": true
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]

Get the current account's pending or active management grant

GET
https://api.nitrosend.com/v1/my/account/management_grant

Only the canonical owner of the selected managed account may use this endpoint.

Response

200OKAccountManagementGrant

Current management grant

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get the current account's pending or active management grant
curl -X GET 'https://api.nitrosend.com/v1/my/account/management_grant'
const response = await fetch('https://api.nitrosend.com/v1/my/account/management_grant', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/account/management_grant')
data = response.json()
{
  "id": 0,
  "status": "pending",
  "permission_set": "operator_v1",
  "manager_account": {
    "id": 0,
    "name": "string"
  },
  "requested_at": "2024-01-15T09:30:00Z",
  "activated_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "released_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Reconcile a consented, paid managed-account grant

POST
https://api.nitrosend.com/v1/my/account/management_grant/confirm

This endpoint cannot record owner consent or bypass paid activation.

Body

application/json
management_grant_idintegerrequired

Exact grant returned by the show endpoint; prevents a stale command from targeting a replacement grant.

Response

200OKAccountManagementGrant

Active management grant

400Bad RequestError

Bad request

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

409ConflictError

The grant cannot transition from its current state

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Reconcile a consented, paid managed-account grant
curl -X POST 'https://api.nitrosend.com/v1/my/account/management_grant/confirm' \
  -H 'Content-Type: application/json' \
  -d '{
    "management_grant_id": 0
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/account/management_grant/confirm', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "management_grant_id": 0
    }),
});

const data = await response.json();
import requests

payload = {
  "management_grant_id": 0
}

response = requests.post('https://api.nitrosend.com/v1/my/account/management_grant/confirm', json=payload)
data = response.json()
Request Body
{
  "management_grant_id": 0
}
{
  "id": 0,
  "status": "pending",
  "permission_set": "operator_v1",
  "manager_account": {
    "id": 0,
    "name": "string"
  },
  "requested_at": "2024-01-15T09:30:00Z",
  "activated_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "released_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Revoke an exact pending or active management grant

POST
https://api.nitrosend.com/v1/my/account/management_grant/revoke

Revocation takes effect on the next REST or MCP request and is idempotent for the exact grant.

Body

application/json
management_grant_idintegerrequired

Exact grant returned by the show endpoint; prevents a stale command from targeting a replacement grant.

Response

200OKAccountManagementGrant

Revoked management grant

400Bad RequestError

Bad request

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

409ConflictError

The grant cannot transition from its current state

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Revoke an exact pending or active management grant
curl -X POST 'https://api.nitrosend.com/v1/my/account/management_grant/revoke' \
  -H 'Content-Type: application/json' \
  -d '{
    "management_grant_id": 0
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/account/management_grant/revoke', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "management_grant_id": 0
    }),
});

const data = await response.json();
import requests

payload = {
  "management_grant_id": 0
}

response = requests.post('https://api.nitrosend.com/v1/my/account/management_grant/revoke', json=payload)
data = response.json()
Request Body
{
  "management_grant_id": 0
}
{
  "id": 0,
  "status": "pending",
  "permission_set": "operator_v1",
  "manager_account": {
    "id": 0,
    "name": "string"
  },
  "requested_at": "2024-01-15T09:30:00Z",
  "activated_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "released_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Get team metadata for the current account

GET
https://api.nitrosend.com/v1/my/account/team

Response

200OKAccountTeam

Team metadata

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get team metadata for the current account
curl -X GET 'https://api.nitrosend.com/v1/my/account/team'
const response = await fetch('https://api.nitrosend.com/v1/my/account/team', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/account/team')
data = response.json()
200
{
  "account": {
    "id": 0,
    "name": "string",
    "avatar": "string",
    "banner": "string",
    "commercial_tier": "unsubscribed",
    "safe_mode_enabled": true,
    "access": {
      "source": "owner",
      "delegated": true,
      "manager_account_id": 0,
      "manager_account_name": "string",
      "management_grant_id": 0,
      "permission_set": "operator_v1",
      "credential_type": "management"
    },
    "billing": {
      "access_policy": "free_allowed",
      "plan_name": "string",
      "plan": {
        "id": 0,
        "name": "string",
        "active": true,
        "probation_recipient_cap_24h": 0,
        "standard_recipient_cap_24h": 0,
        "trusted_recipient_cap_24h": 0,
        "entitlements": {
          "agent_inbox": {
            "enabled": true,
            "max_inboxes": 0,
            "inbound_messages_included": 0,
            "inbound_messages_metered": true,
            "inbound_message_overage_rate_cents": "string",
            "max_inbound_domains": 0,
            "max_apex_domains": 0,
            "apex_mx": true,
            "legacy_forwarding": true,
            "catch_all": true,
            "retention_days": 0,
            "advanced_queue_controls": true
          }
        }
      },
      "spend_cap_monthly_cents": 0,
      "comped": true,
      "overage": {},
      "entitlements": {
        "agent_inbox": {
          "enabled": true,
          "max_inboxes": 0,
          "inbound_messages_included": 0,
          "inbound_messages_metered": true,
          "inbound_message_overage_rate_cents": "string",
          "max_inbound_domains": 0,
          "max_apex_domains": 0,
          "apex_mx": true,
          "legacy_forwarding": true,
          "catch_all": true,
          "retention_days": 0,
          "advanced_queue_controls": true
        }
      },
      "resources": {
        "email": {
          "used": 0,
          "allowance": 0,
          "remaining": 0,
          "overage_rate": 0,
          "mode": "budget",
          "budget": 0,
          "budget_used": 0
        },
        "sms": {
          "used": 0,
          "allowance": 0,
          "remaining": 0,
          "overage_rate": 0,
          "mode": "budget",
          "budget": 0,
          "budget_used": 0
        },
        "ai": {
          "used": 0,
          "allowance": 0,
          "remaining": 0,
          "overage_rate": 0,
          "mode": "budget",
          "budget": 0,
          "budget_used": 0
        }
      },
      "funding": {},
      "provider_route": {},
      "brands": {
        "used": 0,
        "limit": 0,
        "remaining": 0,
        "unlimited": true,
        "can_create": true
      },
      "lifetime": {
        "email_sent": 0,
        "sms_sent": 0,
        "ai_used": 0
      }
    },
    "team": {
      "seat_limit": 0,
      "seat_count": 0,
      "member_count": 0,
      "invite_count": 0,
      "current_role": "string",
      "can_manage_team": true
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "memberships": [
    {
      "id": 0,
      "role": "member",
      "user_id": 0,
      "email": "user@example.com",
      "name": "string",
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ],
  "invites": [
    {
      "id": 0,
      "account_id": 0,
      "email": "user@example.com",
      "role": "member",
      "token": "string",
      "status": "pending",
      "accepted_at": "2024-01-15T09:30:00Z",
      "revoked_at": "2024-01-15T09:30:00Z",
      "expires_at": "2024-01-15T09:30:00Z",
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ],
  "accessible_accounts": [
    {
      "id": 0,
      "name": "string",
      "avatar": "string",
      "banner": "string",
      "commercial_tier": "unsubscribed",
      "safe_mode_enabled": true,
      "access": {
        "source": "owner",
        "delegated": true,
        "manager_account_id": 0,
        "manager_account_name": "string",
        "management_grant_id": 0,
        "permission_set": "operator_v1",
        "credential_type": "management"
      },
      "billing": {
        "access_policy": "free_allowed",
        "plan_name": "string",
        "plan": {
          "id": 0,
          "name": "string",
          "active": true,
          "probation_recipient_cap_24h": 0,
          "standard_recipient_cap_24h": 0,
          "trusted_recipient_cap_24h": 0,
          "entitlements": {
            "agent_inbox": {
              "enabled": true,
              "max_inboxes": 0,
              "inbound_messages_included": 0,
              "inbound_messages_metered": true,
              "inbound_message_overage_rate_cents": "string",
              "max_inbound_domains": 0,
              "max_apex_domains": 0,
              "apex_mx": true,
              "legacy_forwarding": true,
              "catch_all": true,
              "retention_days": 0,
              "advanced_queue_controls": true
            }
          }
        },
        "spend_cap_monthly_cents": 0,
        "comped": true,
        "overage": {},
        "entitlements": {
          "agent_inbox": {
            "enabled": true,
            "max_inboxes": 0,
            "inbound_messages_included": 0,
            "inbound_messages_metered": true,
            "inbound_message_overage_rate_cents": "string",
            "max_inbound_domains": 0,
            "max_apex_domains": 0,
            "apex_mx": true,
            "legacy_forwarding": true,
            "catch_all": true,
            "retention_days": 0,
            "advanced_queue_controls": true
          }
        },
        "resources": {
          "email": {
            "used": 0,
            "allowance": 0,
            "remaining": 0,
            "overage_rate": 0,
            "mode": "budget",
            "budget": 0,
            "budget_used": 0
          },
          "sms": {
            "used": 0,
            "allowance": 0,
            "remaining": 0,
            "overage_rate": 0,
            "mode": "budget",
            "budget": 0,
            "budget_used": 0
          },
          "ai": {
            "used": 0,
            "allowance": 0,
            "remaining": 0,
            "overage_rate": 0,
            "mode": "budget",
            "budget": 0,
            "budget_used": 0
          }
        },
        "funding": {},
        "provider_route": {},
        "brands": {
          "used": 0,
          "limit": 0,
          "remaining": 0,
          "unlimited": true,
          "can_create": true
        },
        "lifetime": {
          "email_sent": 0,
          "sms_sent": 0,
          "ai_used": 0
        }
      },
      "team": {
        "seat_limit": 0,
        "seat_count": 0,
        "member_count": 0,
        "invite_count": 0,
        "current_role": "string",
        "can_manage_team": true
      },
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}

How far one send to an audience gets on the current plan

GET
https://api.nitrosend.com/v1/my/account/reach

Read-only. Reports the recipients per day at the account's sending standing and the emails left this month on the current plan, whether they cover a full send to the audience, and the cheapest listed plan whose first month would. The numbers come from the plan catalogue and this month's usage; the summary sentence is the one every surface shows. Silent (no summary, no recommendation) when the current plan covers the audience.

Parameters

audienceinteger>= 1requiredquery

Number of recipients of one full send

Response

200OKAudienceReach

Reach on the current plan and the recommended plan

422Unprocessable EntityError

audience is not a positive whole number (error_code audience_invalid)

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

How far one send to an audience gets on the current plan
curl -X GET 'https://api.nitrosend.com/v1/my/account/reach'
const response = await fetch('https://api.nitrosend.com/v1/my/account/reach', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/account/reach')
data = response.json()
{
  "audience": 0,
  "cohort": "string",
  "current": {
    "plan_id": 0,
    "slug": "string",
    "name": "string",
    "tier_group": "string",
    "daily_cap": 0,
    "capacity": 0,
    "days_to_reach": 0,
    "covers": true
  },
  "recommended": {
    "plan_id": 0,
    "slug": "string",
    "name": "string",
    "tier_group": "string",
    "daily_cap": 0,
    "capacity": 0,
    "days_to_reach": 0,
    "covers": true
  },
  "covered": true,
  "summary": "string"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

List account memberships (paginated)

GET
https://api.nitrosend.com/v1/my/account/memberships

Parameters

pageinteger1query
perinteger<= 100100query

Response

200OKArray<AccountMembership>

Memberships

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List account memberships (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/account/memberships'
const response = await fetch('https://api.nitrosend.com/v1/my/account/memberships', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/account/memberships')
data = response.json()
200
[
  {
    "id": 0,
    "role": "member",
    "user_id": 0,
    "email": "user@example.com",
    "name": "string",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]

Remove a membership

DELETE
https://api.nitrosend.com/v1/my/account/memberships/{id}

Parameters

idintegerrequiredpath

Response

200OKAccountMembership

Removed membership

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Remove a membership
curl -X DELETE 'https://api.nitrosend.com/v1/my/account/memberships/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/account/memberships/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/account/memberships/{id}')
data = response.json()
200
{
  "id": 0,
  "role": "member",
  "user_id": 0,
  "email": "user@example.com",
  "name": "string",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

Update a membership role

PATCH
https://api.nitrosend.com/v1/my/account/memberships/{id}

Body

application/json
rolestringmemberadmin

Parameters

idintegerrequiredpath

Response

200OKAccountMembership

Updated membership

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update a membership role
curl -X PATCH 'https://api.nitrosend.com/v1/my/account/memberships/{id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "role": "member"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/account/memberships/{id}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "role": "member"
    }),
});

const data = await response.json();
import requests

payload = {
  "role": "member"
}

response = requests.patch('https://api.nitrosend.com/v1/my/account/memberships/{id}', json=payload)
data = response.json()
Request Body
{
  "role": "member"
}
{
  "id": 0,
  "role": "member",
  "user_id": 0,
  "email": "user@example.com",
  "name": "string",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

List account invites (paginated)

GET
https://api.nitrosend.com/v1/my/account/invites

Parameters

pageinteger1query
perinteger<= 100100query

Response

200OKArray<AccountInvite>

Invites

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List account invites (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/account/invites'
const response = await fetch('https://api.nitrosend.com/v1/my/account/invites', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/account/invites')
data = response.json()
200
[
  {
    "id": 0,
    "account_id": 0,
    "email": "user@example.com",
    "role": "member",
    "token": "string",
    "status": "pending",
    "accepted_at": "2024-01-15T09:30:00Z",
    "revoked_at": "2024-01-15T09:30:00Z",
    "expires_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]

Create an account invite

POST
https://api.nitrosend.com/v1/my/account/invites

Body

application/json
emailstring<email>required
rolestringmemberadmin

Response

201CreatedAccountInvite

Created invite

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create an account invite
curl -X POST 'https://api.nitrosend.com/v1/my/account/invites' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "user@example.com",
    "role": "member"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/account/invites', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "email": "user@example.com",
      "role": "member"
    }),
});

const data = await response.json();
import requests

payload = {
  "email": "user@example.com",
  "role": "member"
}

response = requests.post('https://api.nitrosend.com/v1/my/account/invites', json=payload)
data = response.json()
Request Body
{
  "email": "user@example.com",
  "role": "member"
}
{
  "id": 0,
  "account_id": 0,
  "email": "user@example.com",
  "role": "member",
  "token": "string",
  "status": "pending",
  "accepted_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "expires_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Revoke an invite

DELETE
https://api.nitrosend.com/v1/my/account/invites/{id}

Parameters

idintegerrequiredpath

Response

200OKAccountInvite

Revoked invite

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Revoke an invite
curl -X DELETE 'https://api.nitrosend.com/v1/my/account/invites/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/account/invites/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/account/invites/{id}')
data = response.json()
200
{
  "id": 0,
  "account_id": 0,
  "email": "user@example.com",
  "role": "member",
  "token": "string",
  "status": "pending",
  "accepted_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "expires_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

Accept an invite token

POST
https://api.nitrosend.com/v1/my/account/invites/{id}/accept

Parameters

idstringrequiredpath

Response

200OKAccountInvite

Accepted invite

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Accept an invite token
curl -X POST 'https://api.nitrosend.com/v1/my/account/invites/{id}/accept'
const response = await fetch('https://api.nitrosend.com/v1/my/account/invites/{id}/accept', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/account/invites/{id}/accept')
data = response.json()
{
  "id": 0,
  "account_id": 0,
  "email": "user@example.com",
  "role": "member",
  "token": "string",
  "status": "pending",
  "accepted_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "expires_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Affiliate Center

Entitled affiliate link, standing, and lifetime performance

Get the current account's Affiliate Center

GET
https://api.nitrosend.com/v1/my/affiliate

Session/JWT only. API keys are rejected. For an entitled account that is not linked locally, the first read starts one background reconciliation. That reconciliation links an existing Rewardful affiliate by the account owner's email or creates one when absent.

Response

200OKAffiliateCenterPayload

Affiliate Center payload or temporary setup state

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get the current account's Affiliate Center
curl -X GET 'https://api.nitrosend.com/v1/my/affiliate'
const response = await fetch('https://api.nitrosend.com/v1/my/affiliate', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/affiliate')
data = response.json()
{
  "enrolled": true,
  "available": true,
  "state": "active",
  "setup_status": "pending",
  "share_url": "https://example.com",
  "stats": {
    "visitors": 0,
    "leads": 0,
    "conversions": 0
  },
  "earnings": {
    "known": true,
    "total_cents": 0,
    "currency": "string"
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Reconcile the current account's affiliate immediately

POST
https://api.nitrosend.com/v1/my/affiliate

Session/JWT-only repair path. This is idempotent and uses the same existing-or-create behavior as background reconciliation.

Body

application/json
first_namestring
last_namestring

Response

200OKAffiliateCenterPayload

Existing or already-linked affiliate

201CreatedAffiliateCenterPayload

Affiliate identity linked to the account

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

503Service UnavailableError

Upstream service unavailable

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Reconcile the current account's affiliate immediately
curl -X POST 'https://api.nitrosend.com/v1/my/affiliate' \
  -H 'Content-Type: application/json' \
  -d '{
    "first_name": "string",
    "last_name": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/affiliate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "first_name": "string",
      "last_name": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "first_name": "string",
  "last_name": "string"
}

response = requests.post('https://api.nitrosend.com/v1/my/affiliate', json=payload)
data = response.json()
Request Body
{
  "first_name": "string",
  "last_name": "string"
}
{
  "enrolled": true,
  "available": true,
  "state": "active",
  "setup_status": "pending",
  "share_url": "https://example.com",
  "stats": {
    "visitors": 0,
    "leads": 0,
    "conversions": 0
  },
  "earnings": {
    "known": true,
    "total_cents": 0,
    "currency": "string"
  }
}
{
  "enrolled": true,
  "available": true,
  "state": "active",
  "setup_status": "pending",
  "share_url": "https://example.com",
  "stats": {
    "visitors": 0,
    "leads": 0,
    "conversions": 0
  },
  "earnings": {
    "known": true,
    "total_cents": 0,
    "currency": "string"
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Managed Clients

Explicitly enabled client provisioning, consent, and portfolio operations

List the selected manager account's client portfolio

GET
https://api.nitrosend.com/v1/my/managed_accounts

Parameters

pageinteger1query
perinteger<= 10025query
qstringquery
statusManagedAccountLifecycleStatusFilterquery

Use needs_setup to group preparing, awaiting owner, payment required, and payment issue rows.

sortstringcreated_atnameowner_emailstatuscreated_atquery
directionstringascdescdescquery

Response

200OKArray<ManagedAccountProvisioning>

Bounded managed-client portfolio

403ForbiddenError

Not authorized

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List the selected manager account's client portfolio
curl -X GET 'https://api.nitrosend.com/v1/my/managed_accounts'
const response = await fetch('https://api.nitrosend.com/v1/my/managed_accounts', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/managed_accounts')
data = response.json()
[
  {
    "id": 0,
    "external_ref": "string",
    "source": "dashboard",
    "status": "preparing",
    "permission_set": "operator_v1",
    "allowed_actions": [
      "send_invitation"
    ],
    "managed_account": {
      "id": 0,
      "name": "string"
    },
    "owner": {
      "email": "user@example.com"
    },
    "invitation": {
      "expired": true,
      "expires_at": "2024-01-15T09:30:00Z",
      "deadline_at": "2024-01-15T09:30:00Z",
      "notice_sent_at": "2024-01-15T09:30:00Z",
      "claimed_at": "2024-01-15T09:30:00Z",
      "reissues_remaining": 0
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Provision a paid-required, client-owned account

POST
https://api.nitrosend.com/v1/my/managed_accounts

Body

application/json
managed_accountobjectrequired
Show child attributes
owner_emailstring<email>required
owner_first_namestring
owner_last_namestring
account_namestringrequired

Parameters

Idempotency-Keystringrequiredheader

Exact-request idempotency key; changed normalized input conflicts.

Response

200OKManagedAccountProvisioning & object

Exact idempotent replay

201CreatedManagedAccountProvisioning & object

Client provisioned in preparing state; no owner invitation has been sent

403ForbiddenError

Not authorized

409ConflictError

Request conflicts with durable lifecycle or idempotency state

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Provision a paid-required, client-owned account
curl -X POST 'https://api.nitrosend.com/v1/my/managed_accounts' \
  -H 'Content-Type: application/json' \
  -d '{
    "managed_account": {
      "owner_email": "user@example.com",
      "owner_first_name": "string",
      "owner_last_name": "string",
      "account_name": "string"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/managed_accounts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "managed_account": {
        "owner_email": "user@example.com",
        "owner_first_name": "string",
        "owner_last_name": "string",
        "account_name": "string"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "managed_account": {
    "owner_email": "user@example.com",
    "owner_first_name": "string",
    "owner_last_name": "string",
    "account_name": "string"
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/managed_accounts', json=payload)
data = response.json()
Request Body
{
  "managed_account": {
    "owner_email": "user@example.com",
    "owner_first_name": "string",
    "owner_last_name": "string",
    "account_name": "string"
  }
}
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "idempotent_replay": true
}
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "idempotent_replay": true
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get one managed-client portfolio row

GET
https://api.nitrosend.com/v1/my/managed_accounts/{id}

Parameters

idintegerrequiredpath

Response

200OKManagedAccountProvisioning

Managed-client portfolio row

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get one managed-client portfolio row
curl -X GET 'https://api.nitrosend.com/v1/my/managed_accounts/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/managed_accounts/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/managed_accounts/{id}')
data = response.json()
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Invalidate the prior invitation and queue a bounded replacement for owner-only delivery

POST
https://api.nitrosend.com/v1/my/managed_accounts/{id}/resend_invitation

Parameters

idintegerrequiredpath

Response

200OKManagedAccountProvisioning

Updated portfolio row; no invitation capability is returned

403ForbiddenError

Not authorized

409ConflictError

Request conflicts with durable lifecycle or idempotency state

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Invalidate the prior invitation and queue a bounded replacement for owner-only delivery
curl -X POST 'https://api.nitrosend.com/v1/my/managed_accounts/{id}/resend_invitation'
const response = await fetch('https://api.nitrosend.com/v1/my/managed_accounts/{id}/resend_invitation', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/managed_accounts/{id}/resend_invitation')
data = response.json()
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Queue the first bounded owner invitation after client setup is ready

POST
https://api.nitrosend.com/v1/my/managed_accounts/{id}/send_invitation

Parameters

idintegerrequiredpath

Response

200OKManagedAccountProvisioning

Updated portfolio row; no invitation capability is returned

403ForbiddenError

Not authorized

409ConflictError

Request conflicts with durable lifecycle or idempotency state

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Queue the first bounded owner invitation after client setup is ready
curl -X POST 'https://api.nitrosend.com/v1/my/managed_accounts/{id}/send_invitation'
const response = await fetch('https://api.nitrosend.com/v1/my/managed_accounts/{id}/send_invitation', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/managed_accounts/{id}/send_invitation')
data = response.json()
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Queue a cooldown-bound payment reminder to the owner

POST
https://api.nitrosend.com/v1/my/managed_accounts/{id}/payment_reminder

Parameters

idintegerrequiredpath

Response

204No Content

Reminder accepted for delivery

403ForbiddenError

Not authorized

409ConflictError

Request conflicts with durable lifecycle or idempotency state

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Queue a cooldown-bound payment reminder to the owner
curl -X POST 'https://api.nitrosend.com/v1/my/managed_accounts/{id}/payment_reminder'
const response = await fetch('https://api.nitrosend.com/v1/my/managed_accounts/{id}/payment_reminder', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/managed_accounts/{id}/payment_reminder')
data = response.json()
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

End the selected manager's relationship with the client

POST
https://api.nitrosend.com/v1/my/managed_accounts/{id}/release

Parameters

idintegerrequiredpath

Response

200OKManagedAccountProvisioning

Ended managed-client relationship

403ForbiddenError

Not authorized

409ConflictError

Request conflicts with durable lifecycle or idempotency state

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

End the selected manager's relationship with the client
curl -X POST 'https://api.nitrosend.com/v1/my/managed_accounts/{id}/release'
const response = await fetch('https://api.nitrosend.com/v1/my/managed_accounts/{id}/release', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/managed_accounts/{id}/release')
data = response.json()
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

List non-secret provisioning credential metadata

GET
https://api.nitrosend.com/v1/my/account/provisioning_credentials

Response

200OKArray<AccountProvisioningCredential>

Provisioning credential metadata

403ForbiddenError

Not authorized

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List non-secret provisioning credential metadata
curl -X GET 'https://api.nitrosend.com/v1/my/account/provisioning_credentials'
const response = await fetch('https://api.nitrosend.com/v1/my/account/provisioning_credentials', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/account/provisioning_credentials')
data = response.json()
[
  {
    "id": 0,
    "name": "string",
    "scopes": [
      "provision"
    ],
    "secret_hint": "string",
    "expires_at": "2024-01-15T09:30:00Z",
    "last_used_at": "2024-01-15T09:30:00Z",
    "revoked_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z"
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Issue a provisioning credential and reveal its secret once

POST
https://api.nitrosend.com/v1/my/account/provisioning_credentials

Body

application/json
credentialobjectrequired
Show child attributes
namestringrequired
scopesArray<string>provisionmanagerequired
expires_atstring<date-time>

Response

201CreatedAccountProvisioningCredential & object

One-time credential result

403ForbiddenError

Not authorized

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Issue a provisioning credential and reveal its secret once
curl -X POST 'https://api.nitrosend.com/v1/my/account/provisioning_credentials' \
  -H 'Content-Type: application/json' \
  -d '{
    "credential": {
      "name": "string",
      "scopes": [
        "provision"
      ],
      "expires_at": "2024-01-15T09:30:00Z"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/account/provisioning_credentials', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "credential": {
        "name": "string",
        "scopes": [
          "provision"
        ],
        "expires_at": "2024-01-15T09:30:00Z"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "credential": {
    "name": "string",
    "scopes": [
      "provision"
    ],
    "expires_at": "2024-01-15T09:30:00Z"
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/account/provisioning_credentials', json=payload)
data = response.json()
Request Body
{
  "credential": {
    "name": "string",
    "scopes": [
      "provision"
    ],
    "expires_at": "2024-01-15T09:30:00Z"
  }
}
{
  "id": 0,
  "name": "string",
  "scopes": [
    "provision"
  ],
  "secret_hint": "string",
  "expires_at": "2024-01-15T09:30:00Z",
  "last_used_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "secret": "string"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Revoke one manager-bound provisioning credential

DELETE
https://api.nitrosend.com/v1/my/account/provisioning_credentials/{id}

Parameters

idintegerrequiredpath

Response

200OKAccountProvisioningCredential

Revoked credential metadata

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Revoke one manager-bound provisioning credential
curl -X DELETE 'https://api.nitrosend.com/v1/my/account/provisioning_credentials/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/account/provisioning_credentials/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/account/provisioning_credentials/{id}')
data = response.json()
{
  "id": 0,
  "name": "string",
  "scopes": [
    "provision"
  ],
  "secret_hint": "string",
  "expires_at": "2024-01-15T09:30:00Z",
  "last_used_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Inspect a bounded owner consent capability

POST
https://api.nitrosend.com/v1/managed_account_claims/inspect

Body

application/json
claimobjectrequired
Show child attributes
tokenstringrequiredwrite only

Response

200OKManagedAccountClaimInspection

Bounded claim projection

410GoneError

One-time capability is invalid, expired, rotated, or consumed

Inspect a bounded owner consent capability
curl -X POST 'https://api.nitrosend.com/v1/managed_account_claims/inspect' \
  -H 'Content-Type: application/json' \
  -d '{
    "claim": {
      "token": "string"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/managed_account_claims/inspect', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "claim": {
        "token": "string"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "claim": {
    "token": "string"
  }
}

response = requests.post('https://api.nitrosend.com/v1/managed_account_claims/inspect', json=payload)
data = response.json()
Request Body
{
  "claim": {
    "token": "string"
  }
}
{
  "manager": {
    "name": "string"
  },
  "managed_account": {
    "name": "string"
  },
  "owner_email": "string",
  "expires_at": "2024-01-15T09:30:00Z",
  "authentication": "login_required"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Record one-time consent for the exact authenticated owner

POST
https://api.nitrosend.com/v1/managed_account_claims/complete

Body

application/json
claimobjectrequired
Show child attributes
tokenstringrequiredwrite only

Response

200OKManagedAccountClaimCompletion

Consent recorded; status remains payment_required until paid activation

403ForbiddenError

Not authorized

410GoneError

One-time capability is invalid, expired, rotated, or consumed

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Record one-time consent for the exact authenticated owner
curl -X POST 'https://api.nitrosend.com/v1/managed_account_claims/complete' \
  -H 'Content-Type: application/json' \
  -d '{
    "claim": {
      "token": "string"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/managed_account_claims/complete', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "claim": {
        "token": "string"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "claim": {
    "token": "string"
  }
}

response = requests.post('https://api.nitrosend.com/v1/managed_account_claims/complete', json=payload)
data = response.json()
Request Body
{
  "claim": {
    "token": "string"
  }
}
{
  "claimed": true,
  "status": "payment_required",
  "managed_account": {
    "id": 0,
    "name": "string"
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Partner

Provisioning-credential authenticated managed-client operations

List managed clients using a manager-bound credential

GET
https://api.nitrosend.com/v1/partner/managed_accounts

Response

200OKArray<ManagedAccountProvisioning>

Managed-client portfolio

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

Authorization

PartnerProvisioningCredentialhttp (bearer)

Manager-account provisioning credential revealed once at issuance.

List managed clients using a manager-bound credential
curl -X GET 'https://api.nitrosend.com/v1/partner/managed_accounts'
const response = await fetch('https://api.nitrosend.com/v1/partner/managed_accounts', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/partner/managed_accounts')
data = response.json()
[
  {
    "id": 0,
    "external_ref": "string",
    "source": "dashboard",
    "status": "preparing",
    "permission_set": "operator_v1",
    "allowed_actions": [
      "send_invitation"
    ],
    "managed_account": {
      "id": 0,
      "name": "string"
    },
    "owner": {
      "email": "user@example.com"
    },
    "invitation": {
      "expired": true,
      "expires_at": "2024-01-15T09:30:00Z",
      "deadline_at": "2024-01-15T09:30:00Z",
      "notice_sent_at": "2024-01-15T09:30:00Z",
      "claimed_at": "2024-01-15T09:30:00Z",
      "reissues_remaining": 0
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Provision a paid-required client-owned account

POST
https://api.nitrosend.com/v1/partner/managed_accounts

Body

application/json
managed_accountobjectrequired
Show child attributes
external_refstringrequired
owner_emailstring<email>required
owner_first_namestring
owner_last_namestring
account_namestringrequired

Parameters

Idempotency-Keystringrequiredheader

Exact-request idempotency key; changed normalized input conflicts.

Response

200OKManagedAccountProvisioning & object

Exact idempotent replay

201CreatedManagedAccountProvisioning & object

Client provisioned in preparing state; no owner invitation has been sent

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

409ConflictError

Request conflicts with durable lifecycle or idempotency state

422Unprocessable EntityError & object

Validation failed

Authorization

PartnerProvisioningCredentialhttp (bearer)

Manager-account provisioning credential revealed once at issuance.

Provision a paid-required client-owned account
curl -X POST 'https://api.nitrosend.com/v1/partner/managed_accounts' \
  -H 'Content-Type: application/json' \
  -d '{
    "managed_account": {
      "external_ref": "string",
      "owner_email": "user@example.com",
      "owner_first_name": "string",
      "owner_last_name": "string",
      "account_name": "string"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/partner/managed_accounts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "managed_account": {
        "external_ref": "string",
        "owner_email": "user@example.com",
        "owner_first_name": "string",
        "owner_last_name": "string",
        "account_name": "string"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "managed_account": {
    "external_ref": "string",
    "owner_email": "user@example.com",
    "owner_first_name": "string",
    "owner_last_name": "string",
    "account_name": "string"
  }
}

response = requests.post('https://api.nitrosend.com/v1/partner/managed_accounts', json=payload)
data = response.json()
Request Body
{
  "managed_account": {
    "external_ref": "string",
    "owner_email": "user@example.com",
    "owner_first_name": "string",
    "owner_last_name": "string",
    "account_name": "string"
  }
}
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "idempotent_replay": true
}
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "idempotent_replay": true
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get one manager-scoped portfolio row

GET
https://api.nitrosend.com/v1/partner/managed_accounts/{id}

Parameters

idintegerrequiredpath

Response

200OKManagedAccountProvisioning

Managed-client portfolio row

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

PartnerProvisioningCredentialhttp (bearer)

Manager-account provisioning credential revealed once at issuance.

Get one manager-scoped portfolio row
curl -X GET 'https://api.nitrosend.com/v1/partner/managed_accounts/{id}'
const response = await fetch('https://api.nitrosend.com/v1/partner/managed_accounts/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/partner/managed_accounts/{id}')
data = response.json()
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Invalidate the prior invitation and queue a bounded replacement for owner-only delivery

POST
https://api.nitrosend.com/v1/partner/managed_accounts/{id}/resend_invitation

Parameters

idintegerrequiredpath

Response

200OKManagedAccountProvisioning

Updated portfolio row; no invitation capability is returned

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

409ConflictError

Request conflicts with durable lifecycle or idempotency state

Authorization

PartnerProvisioningCredentialhttp (bearer)

Manager-account provisioning credential revealed once at issuance.

Invalidate the prior invitation and queue a bounded replacement for owner-only delivery
curl -X POST 'https://api.nitrosend.com/v1/partner/managed_accounts/{id}/resend_invitation'
const response = await fetch('https://api.nitrosend.com/v1/partner/managed_accounts/{id}/resend_invitation', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/partner/managed_accounts/{id}/resend_invitation')
data = response.json()
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Queue the first bounded owner invitation after client setup is ready

POST
https://api.nitrosend.com/v1/partner/managed_accounts/{id}/send_invitation

Parameters

idintegerrequiredpath

Response

200OKManagedAccountProvisioning

Updated portfolio row; no invitation capability is returned

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

409ConflictError

Request conflicts with durable lifecycle or idempotency state

Authorization

PartnerProvisioningCredentialhttp (bearer)

Manager-account provisioning credential revealed once at issuance.

Queue the first bounded owner invitation after client setup is ready
curl -X POST 'https://api.nitrosend.com/v1/partner/managed_accounts/{id}/send_invitation'
const response = await fetch('https://api.nitrosend.com/v1/partner/managed_accounts/{id}/send_invitation', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/partner/managed_accounts/{id}/send_invitation')
data = response.json()
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

List non-secret agent credential metadata for one managed client

GET
https://api.nitrosend.com/v1/partner/managed_accounts/{provisioning_id}/credentials

Parameters

provisioning_idintegerrequiredpath

Manager-scoped provisioning row id.

Response

200OKArray<AccountManagementCredential>

Agent credential metadata; plaintext secrets are never listed

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

PartnerProvisioningCredentialhttp (bearer)

Manager-account provisioning credential revealed once at issuance.

List non-secret agent credential metadata for one managed client
curl -X GET 'https://api.nitrosend.com/v1/partner/managed_accounts/{provisioning_id}/credentials'
const response = await fetch('https://api.nitrosend.com/v1/partner/managed_accounts/{provisioning_id}/credentials', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/partner/managed_accounts/{provisioning_id}/credentials')
data = response.json()
[
  {
    "id": 0,
    "account_management_grant_id": 0,
    "name": "string",
    "permission_set": "operator_v1",
    "secret_hint": "string",
    "expires_at": "2024-01-15T09:30:00Z",
    "last_used_at": "2024-01-15T09:30:00Z",
    "revoked_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "brand": {
      "id": 0,
      "sid": "string",
      "name": "string"
    }
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Issue one grant- and Brand-pinned agent credential

POST
https://api.nitrosend.com/v1/partner/managed_accounts/{provisioning_id}/credentials

Body

application/json
credentialobjectrequired
Show child attributes
namestringrequired
brand_sidstring

Defaults to the managed Account's default Brand.

expires_atstring<date-time>

Defaults to 90 days and cannot exceed one year.

Parameters

provisioning_idintegerrequiredpath

Manager-scoped provisioning row id.

Response

201CreatedAccountManagementCredential & object

One-time credential result; the secret cannot be recovered

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

409ConflictError

Request conflicts with durable lifecycle or idempotency state

422Unprocessable EntityError & object

Validation failed

Authorization

PartnerProvisioningCredentialhttp (bearer)

Manager-account provisioning credential revealed once at issuance.

Issue one grant- and Brand-pinned agent credential
curl -X POST 'https://api.nitrosend.com/v1/partner/managed_accounts/{provisioning_id}/credentials' \
  -H 'Content-Type: application/json' \
  -d '{
    "credential": {
      "name": "string",
      "brand_sid": "string",
      "expires_at": "2024-01-15T09:30:00Z"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/partner/managed_accounts/{provisioning_id}/credentials', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "credential": {
        "name": "string",
        "brand_sid": "string",
        "expires_at": "2024-01-15T09:30:00Z"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "credential": {
    "name": "string",
    "brand_sid": "string",
    "expires_at": "2024-01-15T09:30:00Z"
  }
}

response = requests.post('https://api.nitrosend.com/v1/partner/managed_accounts/{provisioning_id}/credentials', json=payload)
data = response.json()
Request Body
{
  "credential": {
    "name": "string",
    "brand_sid": "string",
    "expires_at": "2024-01-15T09:30:00Z"
  }
}
{
  "id": 0,
  "account_management_grant_id": 0,
  "name": "string",
  "permission_set": "operator_v1",
  "secret_hint": "string",
  "expires_at": "2024-01-15T09:30:00Z",
  "last_used_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "brand": {
    "id": 0,
    "sid": "string",
    "name": "string"
  },
  "secret": "string"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Revoke one agent credential immediately

DELETE
https://api.nitrosend.com/v1/partner/managed_accounts/{provisioning_id}/credentials/{id}

Parameters

provisioning_idintegerrequiredpath

Manager-scoped provisioning row id.

idintegerrequiredpath

Response

200OKAccountManagementCredential

Revoked credential metadata

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

PartnerProvisioningCredentialhttp (bearer)

Manager-account provisioning credential revealed once at issuance.

Revoke one agent credential immediately
curl -X DELETE 'https://api.nitrosend.com/v1/partner/managed_accounts/{provisioning_id}/credentials/{id}'
const response = await fetch('https://api.nitrosend.com/v1/partner/managed_accounts/{provisioning_id}/credentials/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/partner/managed_accounts/{provisioning_id}/credentials/{id}')
data = response.json()
{
  "id": 0,
  "account_management_grant_id": 0,
  "name": "string",
  "permission_set": "operator_v1",
  "secret_hint": "string",
  "expires_at": "2024-01-15T09:30:00Z",
  "last_used_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "brand": {
    "id": 0,
    "sid": "string",
    "name": "string"
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Billing

Subscription billing and checkout

Create a subscription

POST
https://api.nitrosend.com/v1/my/subscription

Body

application/json
plan_idintegerrequired
stripe_tokenstring | null

Stripe card token for paid-plan creation.

coupon_codestring | null

Customer-entered Stripe promotion code or coupon ID.

Response

201CreatedSubscription

Subscription created

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create a subscription
curl -X POST 'https://api.nitrosend.com/v1/my/subscription' \
  -H 'Content-Type: application/json' \
  -d '{
    "plan_id": 0,
    "stripe_token": "string",
    "coupon_code": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/subscription', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "plan_id": 0,
      "stripe_token": "string",
      "coupon_code": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "plan_id": 0,
  "stripe_token": "string",
  "coupon_code": "string"
}

response = requests.post('https://api.nitrosend.com/v1/my/subscription', json=payload)
data = response.json()
Request Body
{
  "plan_id": 0,
  "stripe_token": "string",
  "coupon_code": "string"
}
{
  "id": 0,
  "plan_id": 0,
  "plan_name": "string",
  "billing_provider": "shopify",
  "source_billing_provider": "shopify",
  "billing_migration_required": true,
  "manage_url": "https://example.com",
  "spend_cap_monthly_cents": 0,
  "shopify_usage_metered": true,
  "status": "pending",
  "interval": "month",
  "currency": "string",
  "subtotal_cents": 0,
  "tax_cents": 0,
  "total_cents": 0,
  "base_price_cents": 0,
  "discount_cents": 0,
  "next_payment_cents": 0,
  "discount_end_at": "2024-01-15T09:30:00Z",
  "activated": true,
  "entitlements": {
    "agent_inbox": {
      "enabled": true,
      "max_inboxes": 0,
      "inbound_messages_included": 0,
      "inbound_messages_metered": true,
      "inbound_message_overage_rate_cents": "string",
      "max_inbound_domains": 0,
      "max_apex_domains": 0,
      "apex_mx": true,
      "legacy_forwarding": true,
      "catch_all": true,
      "retention_days": 0,
      "advanced_queue_controls": true
    }
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Change the current subscription plan

PUT
https://api.nitrosend.com/v1/my/subscription/change

Body

application/json
plan_idintegerrequired
coupon_codestring | null

Customer-entered Stripe promotion code or coupon ID.

Response

200OKSubscription

Subscription updated

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Change the current subscription plan
curl -X PUT 'https://api.nitrosend.com/v1/my/subscription/change' \
  -H 'Content-Type: application/json' \
  -d '{
    "plan_id": 0,
    "coupon_code": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/subscription/change', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "plan_id": 0,
      "coupon_code": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "plan_id": 0,
  "coupon_code": "string"
}

response = requests.put('https://api.nitrosend.com/v1/my/subscription/change', json=payload)
data = response.json()
Request Body
{
  "plan_id": 0,
  "coupon_code": "string"
}
{
  "id": 0,
  "plan_id": 0,
  "plan_name": "string",
  "billing_provider": "shopify",
  "source_billing_provider": "shopify",
  "billing_migration_required": true,
  "manage_url": "https://example.com",
  "spend_cap_monthly_cents": 0,
  "shopify_usage_metered": true,
  "status": "pending",
  "interval": "month",
  "currency": "string",
  "subtotal_cents": 0,
  "tax_cents": 0,
  "total_cents": 0,
  "base_price_cents": 0,
  "discount_cents": 0,
  "next_payment_cents": 0,
  "discount_end_at": "2024-01-15T09:30:00Z",
  "activated": true,
  "entitlements": {
    "agent_inbox": {
      "enabled": true,
      "max_inboxes": 0,
      "inbound_messages_included": 0,
      "inbound_messages_metered": true,
      "inbound_message_overage_rate_cents": "string",
      "max_inbound_domains": 0,
      "max_apex_domains": 0,
      "apex_mx": true,
      "legacy_forwarding": true,
      "catch_all": true,
      "retention_days": 0,
      "advanced_queue_controls": true
    }
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Start a subscription checkout

POST
https://api.nitrosend.com/v1/my/subscription/checkout

Creates or replays one account-scoped plan purchase through the authoritative billing provider. A Stripe-backed active subscription is changed in place rather than creating a parallel subscription. Shopify-managed accounts receive a Shopify-hosted approval URL and never receive a Stripe checkout URL.

Body

application/json
plan_idintegerrequired
idempotency_keystring

Optional body form of Idempotency-Key for compatibility.

Parameters

Idempotency-Keystringheader

Optional stable retry key. The server also reuses an open same-plan checkout.

Response

200OKobject

Subscription changed without external approval

201Createdobject

Provider-hosted checkout created

403ForbiddenError

Billing provider is not ready for checkout

404Not FoundError

Requested plan is not available

409ConflictError

Another checkout is pending or the idempotency key conflicts

422Unprocessable EntityError

Shopify rejected the requested billing terms

503Service UnavailableError

The billing provider could not be reached

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Start a subscription checkout
curl -X POST 'https://api.nitrosend.com/v1/my/subscription/checkout' \
  -H 'Content-Type: application/json' \
  -d '{
    "plan_id": 0,
    "idempotency_key": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/subscription/checkout', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "plan_id": 0,
      "idempotency_key": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "plan_id": 0,
  "idempotency_key": "string"
}

response = requests.post('https://api.nitrosend.com/v1/my/subscription/checkout', json=payload)
data = response.json()
Request Body
{
  "plan_id": 0,
  "idempotency_key": "string"
}
{}
{}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Reconcile and read a plan purchase

GET
https://api.nitrosend.com/v1/my/subscription/checkout_status

Reads the requested plan while approval is pending. Stripe and Shopify are read back before the local state is returned. Omit purchase_id to inspect the latest pending checkout or the current subscription.

Parameters

purchase_idintegerquery

Response

200OKobject

Reconciled plan purchase status

404Not FoundError

Requested plan purchase was not found

503Service UnavailableError

Provider state could not be verified

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Reconcile and read a plan purchase
curl -X GET 'https://api.nitrosend.com/v1/my/subscription/checkout_status'
const response = await fetch('https://api.nitrosend.com/v1/my/subscription/checkout_status', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/subscription/checkout_status')
data = response.json()
{
  "purchase_id": 0,
  "subscription_id": 0,
  "has_subscription": true,
  "status": "string",
  "activated": true,
  "plan_name": "string",
  "provider_status": "string",
  "checkout_url": "https://example.com",
  "approval": {},
  "billing_provider": "string",
  "billing_route": {},
  "manage_url": "https://example.com",
  "entitlements": {},
  "next_action": "string"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Read the current prepaid funding projection and available instruments

GET
https://api.nitrosend.com/v1/my/billing/funding

Response

200OKFundingStatus

Current prepaid funding status

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Read the current prepaid funding projection and available instruments
curl -X GET 'https://api.nitrosend.com/v1/my/billing/funding'
const response = await fetch('https://api.nitrosend.com/v1/my/billing/funding', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/billing/funding')
data = response.json()
200
{
  "state": "string",
  "applies_to": "prepaid_features",
  "subscription_gate": true,
  "currency": "string",
  "available_cents": 0,
  "reserved_cents": 0,
  "deficit_cents": 0,
  "purchase": {
    "available": true,
    "state": "string",
    "reason": "string",
    "default_instrument": "stripe_checkout",
    "instruments": [
      {
        "instrument": "stripe_checkout",
        "provider": "stripe",
        "mode": "hosted_approval",
        "available": true,
        "reason": "string"
      }
    ],
    "currency": "string",
    "minimum_cents": 0,
    "maximum_cents": 0,
    "preset_cents": [
      0
    ]
  },
  "pending_purchase": {
    "id": 0,
    "paid_action_intent_id": "string",
    "provider": "stripe",
    "instrument": "stripe_checkout",
    "status": "requested",
    "currency": "string",
    "requested_cents": 1,
    "requested_display": "string",
    "checkout_url": "https://example.com",
    "approval": {
      "kind": "url",
      "provider": "stripe",
      "url": "https://example.com",
      "target": "self"
    },
    "expires_at": "2024-01-15T09:30:00Z",
    "credited_cents": 0,
    "reversed_cents": 0,
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
}

Start an add-funds purchase with an optional hosted instrument

POST
https://api.nitrosend.com/v1/my/billing/funding/purchases

Creates or replays one local funding purchase. Current public instruments return a provider-hosted approval URL. No request-side credential field is exposed by this endpoint.

Body

application/json
amount_centsinteger>= 1required

Integer service value in minor currency units.

currencystring
instrumentstringstripe_checkoutshopify_one_time

Optional hosted funding instrument. Omit to use the account default.

paid_action_intent_idstring | null

Optional opaque continuation bound to this funding purchase.

Parameters

Idempotency-Keystringrequiredheader

Response

200OKFundingPurchaseResponse

Existing idempotent funding purchase

201CreatedFundingPurchaseResponse

Funding purchase created

409ConflictError

Idempotency key was used for different funding input

422Unprocessable EntityError

Amount or selected funding instrument is unavailable

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Start an add-funds purchase with an optional hosted instrument
curl -X POST 'https://api.nitrosend.com/v1/my/billing/funding/purchases' \
  -H 'Content-Type: application/json' \
  -d '{
    "amount_cents": 1,
    "currency": "string",
    "instrument": "stripe_checkout",
    "paid_action_intent_id": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/billing/funding/purchases', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "amount_cents": 1,
      "currency": "string",
      "instrument": "stripe_checkout",
      "paid_action_intent_id": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "amount_cents": 1,
  "currency": "string",
  "instrument": "stripe_checkout",
  "paid_action_intent_id": "string"
}

response = requests.post('https://api.nitrosend.com/v1/my/billing/funding/purchases', json=payload)
data = response.json()
Request Body
{
  "amount_cents": 1,
  "currency": "string",
  "instrument": "stripe_checkout",
  "paid_action_intent_id": "string"
}
{
  "purchase": {
    "id": 0,
    "paid_action_intent_id": "string",
    "provider": "stripe",
    "instrument": "stripe_checkout",
    "status": "requested",
    "currency": "string",
    "requested_cents": 1,
    "requested_display": "string",
    "checkout_url": "https://example.com",
    "approval": {
      "kind": "url",
      "provider": "stripe",
      "url": "https://example.com",
      "target": "self"
    },
    "expires_at": "2024-01-15T09:30:00Z",
    "credited_cents": 0,
    "reversed_cents": 0,
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "funding": {
    "state": "string",
    "applies_to": "prepaid_features",
    "subscription_gate": true,
    "currency": "string",
    "available_cents": 0,
    "reserved_cents": 0,
    "deficit_cents": 0,
    "purchase": {
      "available": true,
      "state": "string",
      "reason": "string",
      "default_instrument": "stripe_checkout",
      "instruments": [
        {
          "instrument": "stripe_checkout",
          "provider": "stripe",
          "mode": "hosted_approval",
          "available": true,
          "reason": "string"
        }
      ],
      "currency": "string",
      "minimum_cents": 0,
      "maximum_cents": 0,
      "preset_cents": [
        0
      ]
    },
    "pending_purchase": {
      "id": 0,
      "paid_action_intent_id": "string",
      "provider": "stripe",
      "instrument": "stripe_checkout",
      "status": "requested",
      "currency": "string",
      "requested_cents": 1,
      "requested_display": "string",
      "checkout_url": "https://example.com",
      "approval": {
        "kind": "url",
        "provider": "stripe",
        "url": "https://example.com",
        "target": "self"
      },
      "expires_at": "2024-01-15T09:30:00Z",
      "credited_cents": 0,
      "reversed_cents": 0,
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  }
}
{
  "purchase": {
    "id": 0,
    "paid_action_intent_id": "string",
    "provider": "stripe",
    "instrument": "stripe_checkout",
    "status": "requested",
    "currency": "string",
    "requested_cents": 1,
    "requested_display": "string",
    "checkout_url": "https://example.com",
    "approval": {
      "kind": "url",
      "provider": "stripe",
      "url": "https://example.com",
      "target": "self"
    },
    "expires_at": "2024-01-15T09:30:00Z",
    "credited_cents": 0,
    "reversed_cents": 0,
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "funding": {
    "state": "string",
    "applies_to": "prepaid_features",
    "subscription_gate": true,
    "currency": "string",
    "available_cents": 0,
    "reserved_cents": 0,
    "deficit_cents": 0,
    "purchase": {
      "available": true,
      "state": "string",
      "reason": "string",
      "default_instrument": "stripe_checkout",
      "instruments": [
        {
          "instrument": "stripe_checkout",
          "provider": "stripe",
          "mode": "hosted_approval",
          "available": true,
          "reason": "string"
        }
      ],
      "currency": "string",
      "minimum_cents": 0,
      "maximum_cents": 0,
      "preset_cents": [
        0
      ]
    },
    "pending_purchase": {
      "id": 0,
      "paid_action_intent_id": "string",
      "provider": "stripe",
      "instrument": "stripe_checkout",
      "status": "requested",
      "currency": "string",
      "requested_cents": 1,
      "requested_display": "string",
      "checkout_url": "https://example.com",
      "approval": {
        "kind": "url",
        "provider": "stripe",
        "url": "https://example.com",
        "target": "self"
      },
      "expires_at": "2024-01-15T09:30:00Z",
      "credited_cents": 0,
      "reversed_cents": 0,
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Read an account-scoped funding purchase

GET
https://api.nitrosend.com/v1/my/billing/funding/purchases/{id}

Parameters

idstringrequiredpath

Local purchase ID or opaque Stripe Checkout Session ID

Response

200OKFundingPurchaseResponse

Funding purchase status

404Not FoundError

Funding purchase not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Read an account-scoped funding purchase
curl -X GET 'https://api.nitrosend.com/v1/my/billing/funding/purchases/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/billing/funding/purchases/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/billing/funding/purchases/{id}')
data = response.json()
{
  "purchase": {
    "id": 0,
    "paid_action_intent_id": "string",
    "provider": "stripe",
    "instrument": "stripe_checkout",
    "status": "requested",
    "currency": "string",
    "requested_cents": 1,
    "requested_display": "string",
    "checkout_url": "https://example.com",
    "approval": {
      "kind": "url",
      "provider": "stripe",
      "url": "https://example.com",
      "target": "self"
    },
    "expires_at": "2024-01-15T09:30:00Z",
    "credited_cents": 0,
    "reversed_cents": 0,
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "funding": {
    "state": "string",
    "applies_to": "prepaid_features",
    "subscription_gate": true,
    "currency": "string",
    "available_cents": 0,
    "reserved_cents": 0,
    "deficit_cents": 0,
    "purchase": {
      "available": true,
      "state": "string",
      "reason": "string",
      "default_instrument": "stripe_checkout",
      "instruments": [
        {
          "instrument": "stripe_checkout",
          "provider": "stripe",
          "mode": "hosted_approval",
          "available": true,
          "reason": "string"
        }
      ],
      "currency": "string",
      "minimum_cents": 0,
      "maximum_cents": 0,
      "preset_cents": [
        0
      ]
    },
    "pending_purchase": {
      "id": 0,
      "paid_action_intent_id": "string",
      "provider": "stripe",
      "instrument": "stripe_checkout",
      "status": "requested",
      "currency": "string",
      "requested_cents": 1,
      "requested_display": "string",
      "checkout_url": "https://example.com",
      "approval": {
        "kind": "url",
        "provider": "stripe",
        "url": "https://example.com",
        "target": "self"
      },
      "expires_at": "2024-01-15T09:30:00Z",
      "credited_cents": 0,
      "reversed_cents": 0,
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Preview a promotion code or coupon for a subscription plan

POST
https://api.nitrosend.com/v1/my/subscription/coupon_preview

Validates a customer-entered Stripe promotion code or coupon ID against a paid plan and returns display totals for the checkout summary. The final subscription create/change request must still send coupon_code; preview data is not trusted as payment input.

Body

application/json
plan_idintegerrequired
coupon_codestringrequired

Customer-entered Stripe promotion code or coupon ID.

Response

200OKSubscriptionCouponPreview

Coupon preview

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Preview a promotion code or coupon for a subscription plan
curl -X POST 'https://api.nitrosend.com/v1/my/subscription/coupon_preview' \
  -H 'Content-Type: application/json' \
  -d '{
    "plan_id": 0,
    "coupon_code": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/subscription/coupon_preview', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "plan_id": 0,
      "coupon_code": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "plan_id": 0,
  "coupon_code": "string"
}

response = requests.post('https://api.nitrosend.com/v1/my/subscription/coupon_preview', json=payload)
data = response.json()
Request Body
{
  "plan_id": 0,
  "coupon_code": "string"
}
{
  "code": "string",
  "discount_label": "string",
  "discount_cents": 0,
  "subtotal_cents": 0,
  "tax_cents": 0,
  "total_cents": 0,
  "total_after_discount_cents": 0,
  "currency": "string"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Create or exactly replay a resumable paid operation

POST
https://api.nitrosend.com/v1/my/billing/paid_action_intents

Persists encrypted, operation-owned continuation state. The intent is not spend authority and never executes the operation automatically.

Body

application/json
adapter_keystringrequired
adapter_versionstringrequired
operation_idempotency_keystringrequired
state_payloadobjectrequired

Adapter-owned state, validated and encrypted before persistence.

Response

200OKPaidActionIntent

Exact idempotent replay

201CreatedPaidActionIntent

Continuation created

409ConflictError

Operation key reused with different continuation state

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create or exactly replay a resumable paid operation
curl -X POST 'https://api.nitrosend.com/v1/my/billing/paid_action_intents' \
  -H 'Content-Type: application/json' \
  -d '{
    "adapter_key": "string",
    "adapter_version": "string",
    "operation_idempotency_key": "string",
    "state_payload": {}
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/billing/paid_action_intents', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "adapter_key": "string",
      "adapter_version": "string",
      "operation_idempotency_key": "string",
      "state_payload": {}
    }),
});

const data = await response.json();
import requests

payload = {
  "adapter_key": "string",
  "adapter_version": "string",
  "operation_idempotency_key": "string",
  "state_payload": {}
}

response = requests.post('https://api.nitrosend.com/v1/my/billing/paid_action_intents', json=payload)
data = response.json()
Request Body
{
  "adapter_key": "string",
  "adapter_version": "string",
  "operation_idempotency_key": "string",
  "state_payload": {}
}
{
  "id": "string",
  "schema": "nitrosend.paid_action_intent.v1",
  "status": "open",
  "adapter": {
    "key": "string",
    "version": "string"
  },
  "operation_idempotency_key": "string",
  "original_quote_fingerprint": "string",
  "current_quote_fingerprint": "string",
  "quote_changed": true,
  "state_payload": {},
  "quote": {},
  "expires_at": "2024-01-15T09:30:00Z",
  "consumed_at": "2024-01-15T09:30:00Z",
  "cancelled_at": "2024-01-15T09:30:00Z"
}
{
  "id": "string",
  "schema": "nitrosend.paid_action_intent.v1",
  "status": "open",
  "adapter": {
    "key": "string",
    "version": "string"
  },
  "operation_idempotency_key": "string",
  "original_quote_fingerprint": "string",
  "current_quote_fingerprint": "string",
  "quote_changed": true,
  "state_payload": {},
  "quote": {},
  "expires_at": "2024-01-15T09:30:00Z",
  "consumed_at": "2024-01-15T09:30:00Z",
  "cancelled_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Restore and re-quote a paid operation

GET
https://api.nitrosend.com/v1/my/billing/paid_action_intents/{id}

Parameters

idstringrequiredpath

Opaque paid-operation continuation identifier.

Response

200OKPaidActionIntent

Actor-scoped continuation with current terms

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Restore and re-quote a paid operation
curl -X GET 'https://api.nitrosend.com/v1/my/billing/paid_action_intents/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/billing/paid_action_intents/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/billing/paid_action_intents/{id}')
data = response.json()
{
  "id": "string",
  "schema": "nitrosend.paid_action_intent.v1",
  "status": "open",
  "adapter": {
    "key": "string",
    "version": "string"
  },
  "operation_idempotency_key": "string",
  "original_quote_fingerprint": "string",
  "current_quote_fingerprint": "string",
  "quote_changed": true,
  "state_payload": {},
  "quote": {},
  "expires_at": "2024-01-15T09:30:00Z",
  "consumed_at": "2024-01-15T09:30:00Z",
  "cancelled_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Cancel and scrub a paid-operation continuation

POST
https://api.nitrosend.com/v1/my/billing/paid_action_intents/{id}/cancel

Parameters

idstringrequiredpath

Opaque paid-operation continuation identifier.

Response

200OKPaidActionIntent

Cancelled continuation

404Not FoundError

Resource not found

409ConflictError

Terminal continuation cannot be cancelled

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Cancel and scrub a paid-operation continuation
curl -X POST 'https://api.nitrosend.com/v1/my/billing/paid_action_intents/{id}/cancel'
const response = await fetch('https://api.nitrosend.com/v1/my/billing/paid_action_intents/{id}/cancel', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/billing/paid_action_intents/{id}/cancel')
data = response.json()
{
  "id": "string",
  "schema": "nitrosend.paid_action_intent.v1",
  "status": "open",
  "adapter": {
    "key": "string",
    "version": "string"
  },
  "operation_idempotency_key": "string",
  "original_quote_fingerprint": "string",
  "current_quote_fingerprint": "string",
  "quote_changed": true,
  "state_payload": {},
  "quote": {},
  "expires_at": "2024-01-15T09:30:00Z",
  "consumed_at": "2024-01-15T09:30:00Z",
  "cancelled_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Mark a successfully executed paid operation consumed

POST
https://api.nitrosend.com/v1/my/billing/paid_action_intents/{id}/consume

Parameters

idstringrequiredpath

Opaque paid-operation continuation identifier.

Response

200OKPaidActionIntent

Consumed continuation

404Not FoundError

Resource not found

409ConflictError

Continuation is not ready to consume

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Mark a successfully executed paid operation consumed
curl -X POST 'https://api.nitrosend.com/v1/my/billing/paid_action_intents/{id}/consume'
const response = await fetch('https://api.nitrosend.com/v1/my/billing/paid_action_intents/{id}/consume', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/billing/paid_action_intents/{id}/consume')
data = response.json()
{
  "id": "string",
  "schema": "nitrosend.paid_action_intent.v1",
  "status": "open",
  "adapter": {
    "key": "string",
    "version": "string"
  },
  "operation_idempotency_key": "string",
  "original_quote_fingerprint": "string",
  "current_quote_fingerprint": "string",
  "quote_changed": true,
  "state_payload": {},
  "quote": {},
  "expires_at": "2024-01-15T09:30:00Z",
  "consumed_at": "2024-01-15T09:30:00Z",
  "cancelled_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Delivery

Read-only plan/cohort sending allowance and pacing state

Inspect the email sending allowance and pacing

GET
https://api.nitrosend.com/v1/my/delivery/status

Returns a read-only projection of the persisted delivery controls for the selected Brand. This endpoint does not authorize or reserve a send; every send still passes through the canonical admission authority. Pacing describes when admitted work can dispatch and is not itself an admission decision.

Response

200OKDeliveryStatus

Current email sender-capacity and pacing projection

401UnauthorizedError

Not authenticated

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Inspect the email sending allowance and pacing
curl -X GET 'https://api.nitrosend.com/v1/my/delivery/status'
const response = await fetch('https://api.nitrosend.com/v1/my/delivery/status', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/delivery/status')
data = response.json()
{
  "assessment_scope": "account_capacity",
  "admission_status": "allowed",
  "sending_pause": {
    "sending_paused": true,
    "reason": "critical_bounce_rate",
    "occurred_at": "2024-01-15T09:30:00Z",
    "headline": "string",
    "detail": "string",
    "what_to_do": [
      "string"
    ],
    "request_review": "string",
    "recovery_actions": [
      {
        "type": "verify_list",
        "label": "string",
        "url": "string"
      }
    ]
  },
  "commercial_capacity": {
    "source": "plan",
    "window_seconds": 86400,
    "status": "known",
    "limit": 0,
    "reserved": 0,
    "accepted": 0,
    "provider_unknown": 0,
    "remaining": 0
  },
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "pacing_state": {
    "status": "ready",
    "policy_version": "string",
    "queued_quantity": 0,
    "next_dispatch_at": "2024-01-15T09:30:00Z",
    "scopes": [
      {
        "type": "string",
        "status": "ready",
        "next_dispatch_at": "2024-01-15T09:30:00Z",
        "minimum_interval_seconds": 0,
        "feedback_epoch": 0
      }
    ]
  },
  "blocking_control": "account_status",
  "reason_code": "string",
  "issues": [
    {
      "control": "account_status",
      "reason_code": "sending_paused",
      "retryable": true,
      "retry_at": "2024-01-15T09:30:00Z"
    }
  ],
  "retry_at": "2024-01-15T09:30:00Z",
  "observed_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Email Validation

Explicit prepaid email validation quotes and operations

Quote explicit prepaid email validation

POST
https://api.nitrosend.com/v1/my/validation_operations/quote

Classifies one exact current-Brand audience, applies current cached and eligibility evidence, and returns the maximum prepaid charge. It does not hold funds, call a provider, create an operation, or mutate Contacts. Validation has no plan-included allowance.

Body

application/json
One of
any
any
any
any
any

Response

200OKValidationOperationQuote

Non-mutating validation quote

400Bad RequestError

Bad request

401UnauthorizedError

Not authenticated

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Quote explicit prepaid email validation
curl -X POST 'https://api.nitrosend.com/v1/my/validation_operations/quote' \
  -H 'Content-Type: application/json'
const response = await fetch('https://api.nitrosend.com/v1/my/validation_operations/quote', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/validation_operations/quote', headers={'Content-Type': 'application/json'})
data = response.json()
{
  "status": "quoted",
  "source_kind": "contact_channel",
  "quote_digest": "string",
  "counts": {
    "candidate_count": 0,
    "deduplicated_count": 0,
    "cached_count": 0,
    "ineligible_count": 0,
    "eligible_count": 0,
    "pending_count": 0,
    "executing_count": 0,
    "billable_count": 0,
    "not_billable_count": 0,
    "provider_unknown_count": 0,
    "failed_count": 0
  },
  "pricing": {
    "price_book_version": "string",
    "unit_rate_cents": "string",
    "maximum_charge_cents": 0,
    "committed_cents": 0,
    "released_cents": 0,
    "currency": "string",
    "quote_digest": "string",
    "expires_at": "2024-01-15T09:30:00Z",
    "execution_deadline_at": "2024-01-15T09:30:00Z"
  },
  "funding": {
    "route": "direct_prepaid",
    "available": true,
    "reason": "string",
    "usage_event_id": 0,
    "state": "needs_funding",
    "recovery": {}
  },
  "spend": {
    "schema": "nitrosend.spend.v1",
    "status": "ready",
    "route": "direct_prepaid",
    "currency": "string",
    "maximum_charge_cents": 0,
    "balance": {
      "available_cents": 0,
      "reserved_cents": 0,
      "shortfall_cents": 0
    },
    "funding": {},
    "recovery_action": {
      "type": "add_funds",
      "reason": "string",
      "operation": "add_funds",
      "url": "https://example.com",
      "purchase_id": 0,
      "shortfall_cents": 0,
      "minimum_cents": 0,
      "maximum_cents": 0,
      "recommended_cents": 0,
      "preset_cents": [
        0
      ]
    }
  },
  "mutation": false
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Start or resume explicit prepaid email validation

POST
https://api.nitrosend.com/v1/my/validation_operations

Creates one durable operation and holds at most the quoted amount from direct prepaid funds. Reusing the same Idempotency-Key with the same audience returns the same operation; after funding, the same request resumes a needs_funding operation. A changed audience conflicts.

Body

application/json
One of
any
any
any
any
any

Parameters

Idempotency-Keystringrequiredheader

Exact-request idempotency key; changed normalized input conflicts.

Response

202AcceptedValidationOperation

Durable validation operation accepted or replayed

400Bad RequestError

Bad request

401UnauthorizedError

Not authenticated

404Not FoundError

Resource not found

409ConflictError

Request conflicts with durable lifecycle or idempotency state

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Start or resume explicit prepaid email validation
curl -X POST 'https://api.nitrosend.com/v1/my/validation_operations' \
  -H 'Content-Type: application/json'
const response = await fetch('https://api.nitrosend.com/v1/my/validation_operations', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/validation_operations', headers={'Content-Type': 'application/json'})
data = response.json()
{
  "operation_id": "string",
  "status": "requested",
  "source_kind": "contact_channel",
  "item_detail": {
    "status": "available",
    "compacted_at": "2024-01-15T09:30:00Z",
    "item_count": 0
  },
  "counts": {
    "candidate_count": 0,
    "deduplicated_count": 0,
    "cached_count": 0,
    "ineligible_count": 0,
    "eligible_count": 0,
    "pending_count": 0,
    "executing_count": 0,
    "billable_count": 0,
    "not_billable_count": 0,
    "provider_unknown_count": 0,
    "failed_count": 0
  },
  "pricing": {
    "price_book_version": "string",
    "unit_rate_cents": "string",
    "maximum_charge_cents": 0,
    "committed_cents": 0,
    "released_cents": 0,
    "currency": "string",
    "quote_digest": "string",
    "expires_at": "2024-01-15T09:30:00Z",
    "execution_deadline_at": "2024-01-15T09:30:00Z"
  },
  "funding": {
    "route": "direct_prepaid",
    "available": true,
    "reason": "string",
    "usage_event_id": 0,
    "state": "needs_funding",
    "recovery": {}
  },
  "spend": {
    "schema": "nitrosend.spend.v1",
    "status": "ready",
    "route": "direct_prepaid",
    "currency": "string",
    "maximum_charge_cents": 0,
    "balance": {
      "available_cents": 0,
      "reserved_cents": 0,
      "shortfall_cents": 0
    },
    "funding": {},
    "recovery_action": {
      "type": "add_funds",
      "reason": "string",
      "operation": "add_funds",
      "url": "https://example.com",
      "purchase_id": 0,
      "shortfall_cents": 0,
      "minimum_cents": 0,
      "maximum_cents": 0,
      "recommended_cents": 0,
      "preset_cents": [
        0
      ]
    }
  },
  "failure_code": "string",
  "started_at": "2024-01-15T09:30:00Z",
  "completed_at": "2024-01-15T09:30:00Z",
  "next_action": "string"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get an email validation operation

GET
https://api.nitrosend.com/v1/my/validation_operations/{id}

Parameters

idstringrequiredpath

Opaque operation_id returned by the create endpoint.

Response

200OKValidationOperation

Current durable operation state

401UnauthorizedError

Not authenticated

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get an email validation operation
curl -X GET 'https://api.nitrosend.com/v1/my/validation_operations/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/validation_operations/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/validation_operations/{id}')
data = response.json()
{
  "operation_id": "string",
  "status": "requested",
  "source_kind": "contact_channel",
  "item_detail": {
    "status": "available",
    "compacted_at": "2024-01-15T09:30:00Z",
    "item_count": 0
  },
  "counts": {
    "candidate_count": 0,
    "deduplicated_count": 0,
    "cached_count": 0,
    "ineligible_count": 0,
    "eligible_count": 0,
    "pending_count": 0,
    "executing_count": 0,
    "billable_count": 0,
    "not_billable_count": 0,
    "provider_unknown_count": 0,
    "failed_count": 0
  },
  "pricing": {
    "price_book_version": "string",
    "unit_rate_cents": "string",
    "maximum_charge_cents": 0,
    "committed_cents": 0,
    "released_cents": 0,
    "currency": "string",
    "quote_digest": "string",
    "expires_at": "2024-01-15T09:30:00Z",
    "execution_deadline_at": "2024-01-15T09:30:00Z"
  },
  "funding": {
    "route": "direct_prepaid",
    "available": true,
    "reason": "string",
    "usage_event_id": 0,
    "state": "needs_funding",
    "recovery": {}
  },
  "spend": {
    "schema": "nitrosend.spend.v1",
    "status": "ready",
    "route": "direct_prepaid",
    "currency": "string",
    "maximum_charge_cents": 0,
    "balance": {
      "available_cents": 0,
      "reserved_cents": 0,
      "shortfall_cents": 0
    },
    "funding": {},
    "recovery_action": {
      "type": "add_funds",
      "reason": "string",
      "operation": "add_funds",
      "url": "https://example.com",
      "purchase_id": 0,
      "shortfall_cents": 0,
      "minimum_cents": 0,
      "maximum_cents": 0,
      "recommended_cents": 0,
      "preset_cents": [
        0
      ]
    }
  },
  "failure_code": "string",
  "started_at": "2024-01-15T09:30:00Z",
  "completed_at": "2024-01-15T09:30:00Z",
  "next_action": "string"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

List per-candidate email validation results

GET
https://api.nitrosend.com/v1/my/validation_operations/{id}/items

Parameters

idstringrequiredpath

Opaque operation_id returned by the create endpoint.

pageinteger1query
perinteger<= 10030query

Response

200OKArray<ValidationOperationItem>

Paginated operation items

401UnauthorizedError

Not authenticated

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List per-candidate email validation results
curl -X GET 'https://api.nitrosend.com/v1/my/validation_operations/{id}/items'
const response = await fetch('https://api.nitrosend.com/v1/my/validation_operations/{id}/items', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/validation_operations/{id}/items')
data = response.json()
[
  {
    "id": 0,
    "contact_channel_id": 0,
    "status": "pending",
    "billable": true,
    "provider": "string",
    "native_status": "string",
    "verdict": "string",
    "failure_code": "string",
    "result_reference": {},
    "completed_at": "2024-01-15T09:30:00Z"
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Contacts

Contact management

List contacts (paginated)

GET
https://api.nitrosend.com/v1/my/contacts

Parameters

pageinteger1query
limitinteger<= 10050query
searchstringquery

Full-text search across name, email, phone

filtersSegmentFilterExpressionquery

Canonical structured audience filters from the registry exposed by /v1/my/flows/spec and nitro://schema. search remains a separate full-text lookup; filters are applied through the same fail-closed validator used for segments.

list_idintegerquery

Legacy shortcut for a contact_list in [id] filter.

tagstringquery

Legacy shortcut for a contact_tag eq tag filter. Tags are stored as an array of strings under data.tags. For richer tag targeting, use canonical filters.

sortstringcreated_atemails_sentunique_opensclicksopen_rateclick_ratelast_opened_atlast_clicked_atratingquery

Column to sort by. created_at orders by the contact's creation date; the rest are the per-contact engagement rollup fields (see Contact.engagement). Contacts with no rollup row always sort last. Any unrecognised value falls back to the default newest-first order.

directionstringascdescdescquery

Sort direction. Only applies when sort is set.

Response

200OKArray<Contact>

Paginated contacts

503Service UnavailableError

A read did not finish within the request's database time limit (error_code: query_timeout). Nothing was changed; retry after the Retry-After interval. Any GET can return this.

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List contacts (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/contacts'
const response = await fetch('https://api.nitrosend.com/v1/my/contacts', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/contacts')
data = response.json()
[
  {
    "id": 0,
    "brand_id": 0,
    "uuid": "550e8400-e29b-41d4-a716-446655440000",
    "first_name": "string",
    "last_name": "string",
    "source": "string",
    "country_code": "string",
    "flag_emoji": "string",
    "data": {
      "tags": [
        "vip",
        "newsletter"
      ],
      "plan": "pro"
    },
    "subscribed_phone": true,
    "subscribed_email": true,
    "email": "user@example.com",
    "subscribed": {
      "email": true,
      "phone": true
    },
    "verification_status": "verified",
    "enrichment_status": "enriched",
    "mailbox_provider": "gmail",
    "list_ids": [
      0
    ],
    "last_interacted_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z",
    "engagement": {
      "rating": "engaged",
      "emails_sent": 0,
      "unique_opens": 0,
      "clicks": 0,
      "open_rate": 0,
      "click_rate": 0,
      "last_opened_at": "2024-01-15T09:30:00Z",
      "last_clicked_at": "2024-01-15T09:30:00Z"
    },
    "channels": [
      {
        "id": 0,
        "contact_id": 0,
        "kind": "email",
        "value": "string",
        "subscribed": true,
        "verified": true,
        "opt_in_at": "2024-01-15T09:30:00Z",
        "opt_out_at": "2024-01-15T09:30:00Z",
        "sent_count": 0,
        "fail_count": 0,
        "data": {},
        "created_at": "2024-01-15T09:30:00Z",
        "updated_at": "2024-01-15T09:30:00Z"
      }
    ]
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Create a contact

POST
https://api.nitrosend.com/v1/my/contacts

Body

application/json
first_namestring
last_namestring
emailstring<email>

Normalized to lowercase. If the submitted identifiers resolve cleanly to one existing contact in this brand, that contact is updated (200) instead of duplicated. If email and phone identify different contacts in this brand, the request is rejected (422). Creates/updates the email channel with opt_in.

phonestring

E.164 format. Creates/updates phone channel with opt_in

sourcestring
country_codestring
list_idsArray<integer>
dataobject

Custom key-value data. The reserved key tags holds an array of string labels used for segmentation, e.g. {"tags": ["vip", "newsletter"]}.

Merge-on-resolve behavior (create path only): when the submitted email or phone resolves cleanly to an existing contact, data is merged into the contact's existing data rather than replaced. Blank incoming values are ignored; caller-supplied non-reserved keys overwrite their counterparts; the reserved enrichment keys apollo, pdl, attio, hubspot, stripe, shopify, and nitro are preserved from the stored contact; and tags from both sides are unioned. The update endpoint (PATCH /v1/my/contacts/{id}) replaces data wholesale instead.

channels_attributesArray<object>
Show child attributes
kindstringemailphone
valuestring
subscribedboolean

Response

200OKContact

Existing contact updated in place. Returned when the submitted email and/or phone resolves cleanly to one existing contact in this brand.

201CreatedContact

Contact created

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create a contact
curl -X POST 'https://api.nitrosend.com/v1/my/contacts' \
  -H 'Content-Type: application/json' \
  -d '{
    "first_name": "string",
    "last_name": "string",
    "email": "user@example.com",
    "phone": "string",
    "source": "string",
    "country_code": "string",
    "list_ids": [
      0
    ],
    "data": {
      "tags": [
        "vip",
        "newsletter"
      ],
      "plan": "pro"
    },
    "channels_attributes": [
      {
        "kind": "email",
        "value": "string",
        "subscribed": true
      }
    ]
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/contacts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "first_name": "string",
      "last_name": "string",
      "email": "user@example.com",
      "phone": "string",
      "source": "string",
      "country_code": "string",
      "list_ids": [
        0
      ],
      "data": {
        "tags": [
          "vip",
          "newsletter"
        ],
        "plan": "pro"
      },
      "channels_attributes": [
        {
          "kind": "email",
          "value": "string",
          "subscribed": true
        }
      ]
    }),
});

const data = await response.json();
import requests

payload = {
  "first_name": "string",
  "last_name": "string",
  "email": "user@example.com",
  "phone": "string",
  "source": "string",
  "country_code": "string",
  "list_ids": [
    0
  ],
  "data": {
    "tags": [
      "vip",
      "newsletter"
    ],
    "plan": "pro"
  },
  "channels_attributes": [
    {
      "kind": "email",
      "value": "string",
      "subscribed": True
    }
  ]
}

response = requests.post('https://api.nitrosend.com/v1/my/contacts', json=payload)
data = response.json()
Request Body
{
  "first_name": "string",
  "last_name": "string",
  "email": "user@example.com",
  "phone": "string",
  "source": "string",
  "country_code": "string",
  "list_ids": [
    0
  ],
  "data": {
    "tags": [
      "vip",
      "newsletter"
    ],
    "plan": "pro"
  },
  "channels_attributes": [
    {
      "kind": "email",
      "value": "string",
      "subscribed": true
    }
  ]
}
{
  "id": 0,
  "brand_id": 0,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "first_name": "string",
  "last_name": "string",
  "source": "string",
  "country_code": "string",
  "flag_emoji": "string",
  "data": {
    "tags": [
      "vip",
      "newsletter"
    ],
    "plan": "pro"
  },
  "subscribed_phone": true,
  "subscribed_email": true,
  "email": "user@example.com",
  "subscribed": {
    "email": true,
    "phone": true
  },
  "verification_status": "verified",
  "enrichment_status": "enriched",
  "mailbox_provider": "gmail",
  "list_ids": [
    0
  ],
  "last_interacted_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "engagement": {
    "rating": "engaged",
    "emails_sent": 0,
    "unique_opens": 0,
    "clicks": 0,
    "open_rate": 0,
    "click_rate": 0,
    "last_opened_at": "2024-01-15T09:30:00Z",
    "last_clicked_at": "2024-01-15T09:30:00Z"
  },
  "channels": [
    {
      "id": 0,
      "contact_id": 0,
      "kind": "email",
      "value": "string",
      "subscribed": true,
      "verified": true,
      "opt_in_at": "2024-01-15T09:30:00Z",
      "opt_out_at": "2024-01-15T09:30:00Z",
      "sent_count": 0,
      "fail_count": 0,
      "data": {},
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}
{
  "id": 0,
  "brand_id": 0,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "first_name": "string",
  "last_name": "string",
  "source": "string",
  "country_code": "string",
  "flag_emoji": "string",
  "data": {
    "tags": [
      "vip",
      "newsletter"
    ],
    "plan": "pro"
  },
  "subscribed_phone": true,
  "subscribed_email": true,
  "email": "user@example.com",
  "subscribed": {
    "email": true,
    "phone": true
  },
  "verification_status": "verified",
  "enrichment_status": "enriched",
  "mailbox_provider": "gmail",
  "list_ids": [
    0
  ],
  "last_interacted_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "engagement": {
    "rating": "engaged",
    "emails_sent": 0,
    "unique_opens": 0,
    "clicks": 0,
    "open_rate": 0,
    "click_rate": 0,
    "last_opened_at": "2024-01-15T09:30:00Z",
    "last_clicked_at": "2024-01-15T09:30:00Z"
  },
  "channels": [
    {
      "id": 0,
      "contact_id": 0,
      "kind": "email",
      "value": "string",
      "subscribed": true,
      "verified": true,
      "opt_in_at": "2024-01-15T09:30:00Z",
      "opt_out_at": "2024-01-15T09:30:00Z",
      "sent_count": 0,
      "fail_count": 0,
      "data": {},
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get a contact

GET
https://api.nitrosend.com/v1/my/contacts/{id}

Parameters

idintegerrequiredpath

Response

200OKContact

Contact with channels

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get a contact
curl -X GET 'https://api.nitrosend.com/v1/my/contacts/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/contacts/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/contacts/{id}')
data = response.json()
{
  "id": 0,
  "brand_id": 0,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "first_name": "string",
  "last_name": "string",
  "source": "string",
  "country_code": "string",
  "flag_emoji": "string",
  "data": {
    "tags": [
      "vip",
      "newsletter"
    ],
    "plan": "pro"
  },
  "subscribed_phone": true,
  "subscribed_email": true,
  "email": "user@example.com",
  "subscribed": {
    "email": true,
    "phone": true
  },
  "verification_status": "verified",
  "enrichment_status": "enriched",
  "mailbox_provider": "gmail",
  "list_ids": [
    0
  ],
  "last_interacted_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "engagement": {
    "rating": "engaged",
    "emails_sent": 0,
    "unique_opens": 0,
    "clicks": 0,
    "open_rate": 0,
    "click_rate": 0,
    "last_opened_at": "2024-01-15T09:30:00Z",
    "last_clicked_at": "2024-01-15T09:30:00Z"
  },
  "channels": [
    {
      "id": 0,
      "contact_id": 0,
      "kind": "email",
      "value": "string",
      "subscribed": true,
      "verified": true,
      "opt_in_at": "2024-01-15T09:30:00Z",
      "opt_out_at": "2024-01-15T09:30:00Z",
      "sent_count": 0,
      "fail_count": 0,
      "data": {},
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Delete a contact

DELETE
https://api.nitrosend.com/v1/my/contacts/{id}

Parameters

idintegerrequiredpath

Response

200OKContact

Deleted contact

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Delete a contact
curl -X DELETE 'https://api.nitrosend.com/v1/my/contacts/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/contacts/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/contacts/{id}')
data = response.json()
200
{
  "id": 0,
  "brand_id": 0,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "first_name": "string",
  "last_name": "string",
  "source": "string",
  "country_code": "string",
  "flag_emoji": "string",
  "data": {
    "tags": [
      "vip",
      "newsletter"
    ],
    "plan": "pro"
  },
  "subscribed_phone": true,
  "subscribed_email": true,
  "email": "user@example.com",
  "subscribed": {
    "email": true,
    "phone": true
  },
  "verification_status": "verified",
  "enrichment_status": "enriched",
  "mailbox_provider": "gmail",
  "list_ids": [
    0
  ],
  "last_interacted_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "engagement": {
    "rating": "engaged",
    "emails_sent": 0,
    "unique_opens": 0,
    "clicks": 0,
    "open_rate": 0,
    "click_rate": 0,
    "last_opened_at": "2024-01-15T09:30:00Z",
    "last_clicked_at": "2024-01-15T09:30:00Z"
  },
  "channels": [
    {
      "id": 0,
      "contact_id": 0,
      "kind": "email",
      "value": "string",
      "subscribed": true,
      "verified": true,
      "opt_in_at": "2024-01-15T09:30:00Z",
      "opt_out_at": "2024-01-15T09:30:00Z",
      "sent_count": 0,
      "fail_count": 0,
      "data": {},
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}

Update a contact

PATCH
https://api.nitrosend.com/v1/my/contacts/{id}

Body

application/json
first_namestring
last_namestring
emailstring<email>

Changing the email to one already owned by a different contact in the brand is rejected (422).

phonestring
sourcestring
country_codestring
list_idsArray<integer>
dataobject

Custom key-value data. The reserved key tags holds an array of string labels used for segmentation — e.g. {"tags": ["vip", "newsletter"]}.

The data object is replaced wholesale on update. Sending a partial data hash will overwrite any other keys currently stored (e.g. data.plan, enrichment metadata). Reserved enrichment namespaces include apollo, pdl, attio, hubspot, stripe, shopify, and derived nitro. To change a single key, GET the contact, merge your change into the existing data, then PATCH the full merged object back. For add/remove tag semantics across many contacts, use the nitro_manage_audience MCP tool with operation: "bulk_tag".

channels_attributesArray<object>
Show child attributes
idinteger
kindstringemailphone
valuestring
subscribedboolean
_destroyboolean

Parameters

idintegerrequiredpath

Response

200OKContact

Updated contact

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update a contact
curl -X PATCH 'https://api.nitrosend.com/v1/my/contacts/{id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "first_name": "string",
    "last_name": "string",
    "email": "user@example.com",
    "phone": "string",
    "source": "string",
    "country_code": "string",
    "list_ids": [
      0
    ],
    "data": {
      "tags": [
        "vip",
        "newsletter"
      ],
      "plan": "pro"
    },
    "channels_attributes": [
      {
        "id": 0,
        "kind": "email",
        "value": "string",
        "subscribed": true,
        "_destroy": true
      }
    ]
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/contacts/{id}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "first_name": "string",
      "last_name": "string",
      "email": "user@example.com",
      "phone": "string",
      "source": "string",
      "country_code": "string",
      "list_ids": [
        0
      ],
      "data": {
        "tags": [
          "vip",
          "newsletter"
        ],
        "plan": "pro"
      },
      "channels_attributes": [
        {
          "id": 0,
          "kind": "email",
          "value": "string",
          "subscribed": true,
          "_destroy": true
        }
      ]
    }),
});

const data = await response.json();
import requests

payload = {
  "first_name": "string",
  "last_name": "string",
  "email": "user@example.com",
  "phone": "string",
  "source": "string",
  "country_code": "string",
  "list_ids": [
    0
  ],
  "data": {
    "tags": [
      "vip",
      "newsletter"
    ],
    "plan": "pro"
  },
  "channels_attributes": [
    {
      "id": 0,
      "kind": "email",
      "value": "string",
      "subscribed": True,
      "_destroy": True
    }
  ]
}

response = requests.patch('https://api.nitrosend.com/v1/my/contacts/{id}', json=payload)
data = response.json()
Request Body
{
  "first_name": "string",
  "last_name": "string",
  "email": "user@example.com",
  "phone": "string",
  "source": "string",
  "country_code": "string",
  "list_ids": [
    0
  ],
  "data": {
    "tags": [
      "vip",
      "newsletter"
    ],
    "plan": "pro"
  },
  "channels_attributes": [
    {
      "id": 0,
      "kind": "email",
      "value": "string",
      "subscribed": true,
      "_destroy": true
    }
  ]
}
{
  "id": 0,
  "brand_id": 0,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "first_name": "string",
  "last_name": "string",
  "source": "string",
  "country_code": "string",
  "flag_emoji": "string",
  "data": {
    "tags": [
      "vip",
      "newsletter"
    ],
    "plan": "pro"
  },
  "subscribed_phone": true,
  "subscribed_email": true,
  "email": "user@example.com",
  "subscribed": {
    "email": true,
    "phone": true
  },
  "verification_status": "verified",
  "enrichment_status": "enriched",
  "mailbox_provider": "gmail",
  "list_ids": [
    0
  ],
  "last_interacted_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "engagement": {
    "rating": "engaged",
    "emails_sent": 0,
    "unique_opens": 0,
    "clicks": 0,
    "open_rate": 0,
    "click_rate": 0,
    "last_opened_at": "2024-01-15T09:30:00Z",
    "last_clicked_at": "2024-01-15T09:30:00Z"
  },
  "channels": [
    {
      "id": 0,
      "contact_id": 0,
      "kind": "email",
      "value": "string",
      "subscribed": true,
      "verified": true,
      "opt_in_at": "2024-01-15T09:30:00Z",
      "opt_out_at": "2024-01-15T09:30:00Z",
      "sent_count": 0,
      "fail_count": 0,
      "data": {},
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Quote profile enrichment for one or more Contacts

POST
https://api.nitrosend.com/v1/my/contacts/enrichment/quote

Resolves already-current and same-Brand reusable profile evidence before provider work. This endpoint never calls a provider or reserves money. Profile enrichment is priced per successful outcome and has no plan-included allowance.

Body

application/json
contact_idsArray<integer>required

Response

200OKContactEnrichmentQuote

Exact maximum-charge quote and work classification

401UnauthorizedError

Not authenticated

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Quote profile enrichment for one or more Contacts
curl -X POST 'https://api.nitrosend.com/v1/my/contacts/enrichment/quote' \
  -H 'Content-Type: application/json' \
  -d '{
    "contact_ids": [
      0
    ]
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/contacts/enrichment/quote', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "contact_ids": [
        0
      ]
    }),
});

const data = await response.json();
import requests

payload = {
  "contact_ids": [
    0
  ]
}

response = requests.post('https://api.nitrosend.com/v1/my/contacts/enrichment/quote', json=payload)
data = response.json()
Request Body
{
  "contact_ids": [
    0
  ]
}
{
  "selected_count": 0,
  "already_current_count": 0,
  "reusable_count": 0,
  "provider_required_count": 0,
  "unavailable_count": 0,
  "maximum_billable_outcomes": 0,
  "resource": "contact_profile_enrichment",
  "unit_rate_cents": "string",
  "maximum_charge_cents": 0,
  "currency": "USD",
  "price_book_version": "string",
  "available": true,
  "reason": "string",
  "spend": {
    "schema": "nitrosend.spend.v1",
    "status": "ready",
    "route": "direct_prepaid",
    "currency": "string",
    "maximum_charge_cents": 0,
    "balance": {
      "available_cents": 0,
      "reserved_cents": 0,
      "shortfall_cents": 0
    },
    "funding": {},
    "recovery_action": {
      "type": "add_funds",
      "reason": "string",
      "operation": "add_funds",
      "url": "https://example.com",
      "purchase_id": 0,
      "shortfall_cents": 0,
      "minimum_cents": 0,
      "maximum_cents": 0,
      "recommended_cents": 0,
      "preset_cents": [
        0
      ]
    }
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Queue profile enrichment for one or more Contacts

POST
https://api.nitrosend.com/v1/my/contacts/enrichment

Holds the quoted maximum, then queues bounded Contact work. Current evidence is skipped without charge. Fresh same-Brand evidence and usable provider results each commit one outcome; no-match and failures void the hold. This operation does not verify, subscribe, suppress, or qualify an email channel.

Body

application/json
contact_idsArray<integer>required

Parameters

Idempotency-Keystringrequiredheader

Response

200OKContactEnrichmentDispatch

Exact idempotent replay

202AcceptedContactEnrichmentDispatch

Enrichment queued

400Bad RequestError

Bad request

401UnauthorizedError

Not authenticated

402Payment RequiredContactEnrichmentFundingRequired

Account funding changed before the enrichment hold was created

409ConflictError

Idempotency-Key reused with different Contact IDs

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Queue profile enrichment for one or more Contacts
curl -X POST 'https://api.nitrosend.com/v1/my/contacts/enrichment' \
  -H 'Content-Type: application/json' \
  -d '{
    "contact_ids": [
      0
    ]
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/contacts/enrichment', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "contact_ids": [
        0
      ]
    }),
});

const data = await response.json();
import requests

payload = {
  "contact_ids": [
    0
  ]
}

response = requests.post('https://api.nitrosend.com/v1/my/contacts/enrichment', json=payload)
data = response.json()
Request Body
{
  "contact_ids": [
    0
  ]
}
{
  "selected_count": 0,
  "queued_count": 0,
  "already_current_count": 0,
  "reusable_count": 0,
  "provider_required_count": 0,
  "unavailable_count": 0,
  "maximum_charge_cents": 0,
  "currency": "USD",
  "price_book_version": "string",
  "idempotent_replay": true
}
{
  "selected_count": 0,
  "queued_count": 0,
  "already_current_count": 0,
  "reusable_count": 0,
  "provider_required_count": 0,
  "unavailable_count": 0,
  "maximum_charge_cents": 0,
  "currency": "USD",
  "price_book_version": "string",
  "idempotent_replay": true
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "code": "insufficient_balance",
  "message": "string",
  "error": true,
  "error_code": "insufficient_balance",
  "currency": "string",
  "required_cents": 0,
  "available_cents": 0,
  "reserved_cents": 0,
  "shortfall_cents": 0,
  "funding": {},
  "recovery_action": {},
  "spend": {
    "schema": "nitrosend.spend.v1",
    "status": "ready",
    "route": "direct_prepaid",
    "currency": "string",
    "maximum_charge_cents": 0,
    "balance": {
      "available_cents": 0,
      "reserved_cents": 0,
      "shortfall_cents": 0
    },
    "funding": {},
    "recovery_action": {
      "type": "add_funds",
      "reason": "string",
      "operation": "add_funds",
      "url": "https://example.com",
      "purchase_id": 0,
      "shortfall_cents": 0,
      "minimum_cents": 0,
      "maximum_cents": 0,
      "recommended_cents": 0,
      "preset_cents": [
        0
      ]
    }
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Unified activity timeline for a contact

GET
https://api.nitrosend.com/v1/my/contacts/{id}/timeline

Read-only, keyset-paginated feed merging the contact's lifecycle events and email activities into one chronological stream (newest first). Entries are normalised and whitelisted — raw rows are never exposed. Page using the cursor returned as next_cursor.

Parameters

idintegerrequiredpath
cursorstringquery

Opaque keyset cursor from a prior next_cursor.

limitinteger<= 10025query

Response

200OKobject

A page of timeline entries, newest first

401UnauthorizedError

Not authenticated

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Unified activity timeline for a contact
curl -X GET 'https://api.nitrosend.com/v1/my/contacts/{id}/timeline'
const response = await fetch('https://api.nitrosend.com/v1/my/contacts/{id}/timeline', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/contacts/{id}/timeline')
data = response.json()
{
  "entries": [
    {
      "id": "string",
      "kind": "event",
      "type": "string",
      "title": "string",
      "occurred_at": "2024-01-15T09:30:00Z",
      "meta": {}
    }
  ],
  "next_cursor": "string"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Enrichment facts for a contact

GET
https://api.nitrosend.com/v1/my/contacts/{id}/enrichment

Read-only enrichment facts resolved into display rows. Facts sourced from an integration you have connected are attributed with that integration's name; facts from other sources are returned unattributed.

Parameters

idintegerrequiredpath

Response

200OKobject

The contact's resolved enrichment rows

401UnauthorizedError

Not authenticated

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Enrichment facts for a contact
curl -X GET 'https://api.nitrosend.com/v1/my/contacts/{id}/enrichment'
const response = await fetch('https://api.nitrosend.com/v1/my/contacts/{id}/enrichment', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/contacts/{id}/enrichment')
data = response.json()
{
  "rows": [
    {
      "key": "string",
      "group": "professional",
      "display_value": "string",
      "value_type": "string",
      "confidence": 0,
      "stale": true,
      "synced_at": "2024-01-15T09:30:00Z",
      "integration_label": "string"
    }
  ],
  "field_count": 0,
  "summary": {
    "field_count": 0,
    "stale_count": 0,
    "latest_synced_at": "2024-01-15T09:30:00Z",
    "groups": {}
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

List the field catalog for this account

GET
https://api.nitrosend.com/v1/my/contacts/fields

Returns the structured field catalog: one row per known field for this account, with key, category, type, label, promotion state, and async fill-rate. Fields are lazily registered the first time a key is seen (import, API write, or enrichment). Use PATCH /v1/my/contacts/fields/:id to update promoted or label.

Response

200OKArray<FieldCatalog>

Field catalog rows ordered by category and label

401UnauthorizedError

Not authenticated

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List the field catalog for this account
curl -X GET 'https://api.nitrosend.com/v1/my/contacts/fields'
const response = await fetch('https://api.nitrosend.com/v1/my/contacts/fields', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/contacts/fields')
data = response.json()
[
  {
    "id": 0,
    "key": "string",
    "category": "contact",
    "field_type": "string",
    "presentation_type": "text",
    "presentation_options": {},
    "label": "string",
    "display_label": "string",
    "source_key": "string",
    "source_name": "string",
    "object_label": "string",
    "source_field_label": "string",
    "merge_tag": "string",
    "promoted": true,
    "fill_rate": "75.0",
    "fill_rate_refreshed_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Update a field catalog row (owner/admin only)

PATCH
https://api.nitrosend.com/v1/my/contacts/fields/{id}

Updates the promoted flag and/or the human-readable label for a field catalog row. Restricted to account owners and admins. The key, category, and field_type of a row are immutable.

Body

application/json
promotedboolean

Pin this field as a default column in the contacts grid.

labelstring

Override the human-readable label for this field.

Parameters

idintegerrequiredpath

Response

200OKFieldCatalog

Updated field catalog row

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update a field catalog row (owner/admin only)
curl -X PATCH 'https://api.nitrosend.com/v1/my/contacts/fields/{id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "promoted": true,
    "label": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/contacts/fields/{id}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "promoted": true,
      "label": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "promoted": True,
  "label": "string"
}

response = requests.patch('https://api.nitrosend.com/v1/my/contacts/fields/{id}', json=payload)
data = response.json()
Request Body
{
  "promoted": true,
  "label": "string"
}
{
  "id": 0,
  "key": "string",
  "category": "contact",
  "field_type": "string",
  "presentation_type": "text",
  "presentation_options": {},
  "label": "string",
  "display_label": "string",
  "source_key": "string",
  "source_name": "string",
  "object_label": "string",
  "source_field_label": "string",
  "merge_tag": "string",
  "promoted": true,
  "fill_rate": "75.0",
  "fill_rate_refreshed_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Imports

Bulk CSV import jobs

Reserve a direct-upload blob

POST
https://api.nitrosend.com/v1/direct_uploads

Creates an Active Storage direct-upload reservation and returns a signed_id, presigned upload URL, and required upload headers. For CSV imports, send purpose: import, PUT the file bytes to direct_upload.url, then submit the returned signed_id to POST /v1/my/imports. For image media assets, send purpose: image or purpose: media_asset, PUT the image bytes to direct_upload.url, then submit the returned signed_id to POST /v1/my/images.

Body

application/json
purposestringimportimagemedia_asset

Set to import for CSV contact imports, or image/media_asset for image media assets.

blobobjectrequired
Show child attributes
filenamestringrequired
byte_sizeintegerrequired
checksumstringrequired

Base64-encoded MD5 checksum for Active Storage direct upload.

content_typestring
metadataobject

Response

200OKDirectUpload

Direct-upload reservation

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Reserve a direct-upload blob
curl -X POST 'https://api.nitrosend.com/v1/direct_uploads' \
  -H 'Content-Type: application/json' \
  -d '{
    "purpose": "import",
    "blob": {
      "filename": "contacts.csv",
      "byte_size": 1048576,
      "checksum": "string",
      "content_type": "text/csv",
      "metadata": {}
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/direct_uploads', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "purpose": "import",
      "blob": {
        "filename": "contacts.csv",
        "byte_size": 1048576,
        "checksum": "string",
        "content_type": "text/csv",
        "metadata": {}
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "purpose": "import",
  "blob": {
    "filename": "contacts.csv",
    "byte_size": 1048576,
    "checksum": "string",
    "content_type": "text/csv",
    "metadata": {}
  }
}

response = requests.post('https://api.nitrosend.com/v1/direct_uploads', json=payload)
data = response.json()
Request Body
{
  "purpose": "import",
  "blob": {
    "filename": "contacts.csv",
    "byte_size": 1048576,
    "checksum": "string",
    "content_type": "text/csv",
    "metadata": {}
  }
}
{
  "signed_id": "string",
  "filename": "string",
  "byte_size": 0,
  "content_type": "string",
  "direct_upload": {
    "url": "https://example.com",
    "headers": {}
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

List import jobs

GET
https://api.nitrosend.com/v1/my/imports

Parameters

pageinteger1query
limitinteger<= 10025query

Response

200OKArray<Import>

Paginated import jobs

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List import jobs
curl -X GET 'https://api.nitrosend.com/v1/my/imports'
const response = await fetch('https://api.nitrosend.com/v1/my/imports', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/imports')
data = response.json()
200
[
  {
    "id": 0,
    "resource": "contacts",
    "parser": "default",
    "status": "pending",
    "total_rows": 0,
    "success_rows": 0,
    "failed_rows": 0,
    "warning_rows": 0,
    "progress": {
      "status": "pending",
      "pct": 0,
      "stages": [
        {
          "key": "string",
          "label": "string",
          "count": 0,
          "state": "done"
        }
      ]
    },
    "import_errors": [
      [
        0
      ]
    ],
    "import_warnings": [
      [
        0
      ]
    ],
    "columns": {},
    "options": {},
    "assigned_list_ids": [
      0
    ],
    "assigned_lists": [
      {
        "id": 0,
        "name": "string"
      }
    ],
    "guardrail": {
      "tier": "auto",
      "status": "ok",
      "standing": "probation",
      "max_rows": 250000
    },
    "started_at": "2024-01-15T09:30:00Z",
    "ended_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z"
  }
]

Start a CSV import

POST
https://api.nitrosend.com/v1/my/imports

Enqueues an import job from an Active Storage direct-upload signed_id. Create the blob through POST /v1/direct_uploads with purpose=import, PUT the file to the returned direct-upload URL, then submit the returned signed_id here. Poll GET /v1/my/imports/{id} for status, row counts, and row-level errors.

For contact imports, pass options as a JSON object or JSON string with list_ids to assign imported contacts to one or more lists, e.g. {"list_ids":[88]}.

Body

application/json
signed_idstringrequired

Active Storage blob signed ID returned by /v1/direct_uploads.

resourcestringcontactscontacts
parserstringdefaultdefault
dry_runbooleanfalse
columnsobject | string

CSV column mapping as a JSON object or JSON string.

optionsobject | string

Import options as a JSON object or JSON string.

Response

201CreatedImport

Import queued

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Start a CSV import
curl -X POST 'https://api.nitrosend.com/v1/my/imports' \
  -H 'Content-Type: application/json' \
  -d '{
    "signed_id": "string",
    "resource": "contacts",
    "parser": "default",
    "dry_run": false,
    "columns": {
      "email": "Email",
      "first_name": "First Name"
    },
    "options": {
      "list_ids": [
        88
      ]
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/imports', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "signed_id": "string",
      "resource": "contacts",
      "parser": "default",
      "dry_run": false,
      "columns": {
        "email": "Email",
        "first_name": "First Name"
      },
      "options": {
        "list_ids": [
          88
        ]
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "signed_id": "string",
  "resource": "contacts",
  "parser": "default",
  "dry_run": False,
  "columns": {
    "email": "Email",
    "first_name": "First Name"
  },
  "options": {
    "list_ids": [
      88
    ]
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/imports', json=payload)
data = response.json()
Request Body
{
  "signed_id": "string",
  "resource": "contacts",
  "parser": "default",
  "dry_run": false,
  "columns": {
    "email": "Email",
    "first_name": "First Name"
  },
  "options": {
    "list_ids": [
      88
    ]
  }
}
{
  "id": 0,
  "resource": "contacts",
  "parser": "default",
  "status": "pending",
  "total_rows": 0,
  "success_rows": 0,
  "failed_rows": 0,
  "warning_rows": 0,
  "progress": {
    "status": "pending",
    "pct": 0,
    "stages": [
      {
        "key": "string",
        "label": "string",
        "count": 0,
        "state": "done"
      }
    ]
  },
  "import_errors": [
    [
      0
    ]
  ],
  "import_warnings": [
    [
      0
    ]
  ],
  "columns": {},
  "options": {},
  "assigned_list_ids": [
    0
  ],
  "assigned_lists": [
    {
      "id": 0,
      "name": "string"
    }
  ],
  "guardrail": {
    "tier": "auto",
    "status": "ok",
    "standing": "probation",
    "max_rows": 250000
  },
  "started_at": "2024-01-15T09:30:00Z",
  "ended_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get import schema metadata

GET
https://api.nitrosend.com/v1/my/imports/spec

Parameters

resourcestringcontactsquery

Optional resource name. Omit to list all schemas.

Response

200OKImportSpec | object

Import schema metadata

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get import schema metadata
curl -X GET 'https://api.nitrosend.com/v1/my/imports/spec'
const response = await fetch('https://api.nitrosend.com/v1/my/imports/spec', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/imports/spec')
data = response.json()
{
  "resource": "contacts",
  "parser": "default",
  "ui": {},
  "required_rules": {},
  "fields": [
    {}
  ],
  "guardrails": {
    "standing": "trusted",
    "max_rows": null,
    "max_file_size_bytes": 2147483648,
    "max_file_size_mb": 2048,
    "max_active_imports": 10,
    "create_rate_limit_per_minute": 10,
    "direct_upload_rate_limit_per_minute": 30,
    "write_modes": [
      "real"
    ]
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get import job status

GET
https://api.nitrosend.com/v1/my/imports/{id}

Parameters

idintegerrequiredpath

Response

200OKImport

Import job with status, counts, and row errors

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get import job status
curl -X GET 'https://api.nitrosend.com/v1/my/imports/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/imports/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/imports/{id}')
data = response.json()
{
  "id": 0,
  "resource": "contacts",
  "parser": "default",
  "status": "pending",
  "total_rows": 0,
  "success_rows": 0,
  "failed_rows": 0,
  "warning_rows": 0,
  "progress": {
    "status": "pending",
    "pct": 0,
    "stages": [
      {
        "key": "string",
        "label": "string",
        "count": 0,
        "state": "done"
      }
    ]
  },
  "import_errors": [
    [
      0
    ]
  ],
  "import_warnings": [
    [
      0
    ]
  ],
  "columns": {},
  "options": {},
  "assigned_list_ids": [
    0
  ],
  "assigned_lists": [
    {
      "id": 0,
      "name": "string"
    }
  ],
  "guardrail": {
    "tier": "auto",
    "status": "ok",
    "standing": "probation",
    "max_rows": 250000
  },
  "started_at": "2024-01-15T09:30:00Z",
  "ended_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Delete an import record

DELETE
https://api.nitrosend.com/v1/my/imports/{id}

Parameters

idintegerrequiredpath

Response

200OKImport

Deleted import

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Delete an import record
curl -X DELETE 'https://api.nitrosend.com/v1/my/imports/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/imports/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/imports/{id}')
data = response.json()
{
  "id": 0,
  "resource": "contacts",
  "parser": "default",
  "status": "pending",
  "total_rows": 0,
  "success_rows": 0,
  "failed_rows": 0,
  "warning_rows": 0,
  "progress": {
    "status": "pending",
    "pct": 0,
    "stages": [
      {
        "key": "string",
        "label": "string",
        "count": 0,
        "state": "done"
      }
    ]
  },
  "import_errors": [
    [
      0
    ]
  ],
  "import_warnings": [
    [
      0
    ]
  ],
  "columns": {},
  "options": {},
  "assigned_list_ids": [
    0
  ],
  "assigned_lists": [
    {
      "id": 0,
      "name": "string"
    }
  ],
  "guardrail": {
    "tier": "auto",
    "status": "ok",
    "standing": "probation",
    "max_rows": 250000
  },
  "started_at": "2024-01-15T09:30:00Z",
  "ended_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Cancel a pending or processing import

POST
https://api.nitrosend.com/v1/my/imports/{id}/cancel

Parameters

idintegerrequiredpath

Response

200OKImport

Canceled import

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Cancel a pending or processing import
curl -X POST 'https://api.nitrosend.com/v1/my/imports/{id}/cancel'
const response = await fetch('https://api.nitrosend.com/v1/my/imports/{id}/cancel', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/imports/{id}/cancel')
data = response.json()
{
  "id": 0,
  "resource": "contacts",
  "parser": "default",
  "status": "pending",
  "total_rows": 0,
  "success_rows": 0,
  "failed_rows": 0,
  "warning_rows": 0,
  "progress": {
    "status": "pending",
    "pct": 0,
    "stages": [
      {
        "key": "string",
        "label": "string",
        "count": 0,
        "state": "done"
      }
    ]
  },
  "import_errors": [
    [
      0
    ]
  ],
  "import_warnings": [
    [
      0
    ]
  ],
  "columns": {},
  "options": {},
  "assigned_list_ids": [
    0
  ],
  "assigned_lists": [
    {
      "id": 0,
      "name": "string"
    }
  ],
  "guardrail": {
    "tier": "auto",
    "status": "ok",
    "standing": "probation",
    "max_rows": 250000
  },
  "started_at": "2024-01-15T09:30:00Z",
  "ended_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Exports

Contact CSV export jobs

List export jobs

GET
https://api.nitrosend.com/v1/my/exports

Parameters

pageinteger1query
limitinteger<= 10025query

Response

200OKArray<Export>

Paginated export jobs

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List export jobs
curl -X GET 'https://api.nitrosend.com/v1/my/exports'
const response = await fetch('https://api.nitrosend.com/v1/my/exports', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/exports')
data = response.json()
200
[
  {
    "id": 0,
    "resource": "contacts",
    "format": "csv",
    "status": "pending",
    "total_rows": 0,
    "rows_written": 0,
    "error_message": "string",
    "ready": true,
    "download_path": "string",
    "progress": {
      "status": "pending",
      "pct": 0,
      "stages": [
        {
          "key": "string",
          "label": "string",
          "count": 0,
          "state": "done"
        }
      ]
    },
    "started_at": "2024-01-15T09:30:00Z",
    "ended_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z"
  }
]

Start a contact export

POST
https://api.nitrosend.com/v1/my/exports

Enqueues an export job that builds a CSV of the brand's contacts and attaches it to the export record. The same filters as GET /v1/my/contacts are supported (search, list_id, tag). Custom fields stored on contacts are emitted as additional CSV columns.

Poll GET /v1/my/exports/{id} until ready is true, then download the file from the returned download_path.

Body

application/json
resourcestringcontactscontacts
searchstring

Free-text filter, matching the contacts list search.

list_idinteger

Restrict the export to contacts in this list.

tagstring

Restrict the export to contacts with this tag.

Response

201CreatedExport

Export queued

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Start a contact export
curl -X POST 'https://api.nitrosend.com/v1/my/exports' \
  -H 'Content-Type: application/json' \
  -d '{
    "resource": "contacts",
    "search": "string",
    "list_id": 0,
    "tag": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/exports', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "resource": "contacts",
      "search": "string",
      "list_id": 0,
      "tag": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "resource": "contacts",
  "search": "string",
  "list_id": 0,
  "tag": "string"
}

response = requests.post('https://api.nitrosend.com/v1/my/exports', json=payload)
data = response.json()
Request Body
{
  "resource": "contacts",
  "search": "string",
  "list_id": 0,
  "tag": "string"
}
{
  "id": 0,
  "resource": "contacts",
  "format": "csv",
  "status": "pending",
  "total_rows": 0,
  "rows_written": 0,
  "error_message": "string",
  "ready": true,
  "download_path": "string",
  "progress": {
    "status": "pending",
    "pct": 0,
    "stages": [
      {
        "key": "string",
        "label": "string",
        "count": 0,
        "state": "done"
      }
    ]
  },
  "started_at": "2024-01-15T09:30:00Z",
  "ended_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get an export job

GET
https://api.nitrosend.com/v1/my/exports/{id}

Parameters

idintegerrequiredpath

Response

200OKExport

Export job

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get an export job
curl -X GET 'https://api.nitrosend.com/v1/my/exports/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/exports/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/exports/{id}')
data = response.json()
{
  "id": 0,
  "resource": "contacts",
  "format": "csv",
  "status": "pending",
  "total_rows": 0,
  "rows_written": 0,
  "error_message": "string",
  "ready": true,
  "download_path": "string",
  "progress": {
    "status": "pending",
    "pct": 0,
    "stages": [
      {
        "key": "string",
        "label": "string",
        "count": 0,
        "state": "done"
      }
    ]
  },
  "started_at": "2024-01-15T09:30:00Z",
  "ended_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Download a completed export file

GET
https://api.nitrosend.com/v1/my/exports/{id}/download

Returns the CSV file once the export status is complete.

Parameters

idintegerrequiredpath

Response

200OKstring<binary>

CSV file

404Not FoundError

Resource not found

422Unprocessable EntityError

Export is not ready

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Download a completed export file
curl -X GET 'https://api.nitrosend.com/v1/my/exports/{id}/download'
const response = await fetch('https://api.nitrosend.com/v1/my/exports/{id}/download', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/exports/{id}/download')
data = response.json()
<binary>
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Lists

Contact lists

List contact lists (paginated)

GET
https://api.nitrosend.com/v1/my/lists

Parameters

namestringquery

Exact case-insensitive list name filter

pageinteger1query
limitinteger<= 10025query

Response

200OKArray<ContactList>

Paginated contact lists

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List contact lists (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/lists'
const response = await fetch('https://api.nitrosend.com/v1/my/lists', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/lists')
data = response.json()
200
[
  {
    "id": 0,
    "account_id": 0,
    "brand_id": 0,
    "name": "string",
    "contacts_count": 0,
    "segment_id": 0,
    "stale": true,
    "last_populated_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]

Create a contact list

POST
https://api.nitrosend.com/v1/my/lists

Body

application/json
namestringrequired
segment_idinteger | null
contact_idsArray<integer>

Response

201CreatedContactList

List created

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create a contact list
curl -X POST 'https://api.nitrosend.com/v1/my/lists' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string",
    "segment_id": 0,
    "contact_ids": [
      0
    ]
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/lists', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string",
      "segment_id": 0,
      "contact_ids": [
        0
      ]
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string",
  "segment_id": 0,
  "contact_ids": [
    0
  ]
}

response = requests.post('https://api.nitrosend.com/v1/my/lists', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "segment_id": 0,
  "contact_ids": [
    0
  ]
}
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "name": "string",
  "contacts_count": 0,
  "segment_id": 0,
  "stale": true,
  "last_populated_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get a contact list

GET
https://api.nitrosend.com/v1/my/lists/{id}

Parameters

idintegerrequiredpath

Response

200OKContactList

Contact list

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get a contact list
curl -X GET 'https://api.nitrosend.com/v1/my/lists/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/lists/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/lists/{id}')
data = response.json()
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "name": "string",
  "contacts_count": 0,
  "segment_id": 0,
  "stale": true,
  "last_populated_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Delete a contact list

DELETE
https://api.nitrosend.com/v1/my/lists/{id}

Parameters

idintegerrequiredpath

Response

200OKContactList

Deleted list

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Delete a contact list
curl -X DELETE 'https://api.nitrosend.com/v1/my/lists/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/lists/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/lists/{id}')
data = response.json()
200
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "name": "string",
  "contacts_count": 0,
  "segment_id": 0,
  "stale": true,
  "last_populated_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

Update a contact list

PATCH
https://api.nitrosend.com/v1/my/lists/{id}

Body

application/json
namestring
segment_idinteger | null
contact_idsArray<integer>

Parameters

idintegerrequiredpath

Response

200OKContactList

Updated list

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update a contact list
curl -X PATCH 'https://api.nitrosend.com/v1/my/lists/{id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string",
    "segment_id": 0,
    "contact_ids": [
      0
    ]
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/lists/{id}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string",
      "segment_id": 0,
      "contact_ids": [
        0
      ]
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string",
  "segment_id": 0,
  "contact_ids": [
    0
  ]
}

response = requests.patch('https://api.nitrosend.com/v1/my/lists/{id}', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "segment_id": 0,
  "contact_ids": [
    0
  ]
}
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "name": "string",
  "contacts_count": 0,
  "segment_id": 0,
  "stale": true,
  "last_populated_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get delete warning metadata for a contact list

GET
https://api.nitrosend.com/v1/my/lists/{id}/delete_warning

Parameters

idintegerrequiredpath

Response

200OKListDeleteWarning

Flows connected to this list

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get delete warning metadata for a contact list
curl -X GET 'https://api.nitrosend.com/v1/my/lists/{id}/delete_warning'
const response = await fetch('https://api.nitrosend.com/v1/my/lists/{id}/delete_warning', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/lists/{id}/delete_warning')
data = response.json()
200
{
  "campaign_names": [
    "string"
  ],
  "flow_names": [
    "string"
  ]
}

Add or remove existing contacts from a list by email

POST
https://api.nitrosend.com/v1/my/lists/{id}/contacts/bulk

Public REST equivalent of the list membership batch primitive. The endpoint resolves existing contacts by email within the current brand and adds or removes memberships idempotently. It does not create contacts; emails with no current-brand contact are returned in not_found.

Body

application/json
actionstringaddremoverequired

Add existing contacts to the list or remove them from it.

emailsArray<string>required

Parameters

idintegerrequiredpath

Response

200OKBulkListContactsResponse

Bulk list membership result

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Add or remove existing contacts from a list by email
curl -X POST 'https://api.nitrosend.com/v1/my/lists/{id}/contacts/bulk' \
  -H 'Content-Type: application/json' \
  -d '{
    "action": "add",
    "emails": [
      "user@example.com"
    ]
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/lists/{id}/contacts/bulk', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "action": "add",
      "emails": [
        "user@example.com"
      ]
    }),
});

const data = await response.json();
import requests

payload = {
  "action": "add",
  "emails": [
    "user@example.com"
  ]
}

response = requests.post('https://api.nitrosend.com/v1/my/lists/{id}/contacts/bulk', json=payload)
data = response.json()
Request Body
{
  "action": "add",
  "emails": [
    "user@example.com"
  ]
}
{
  "action": "add",
  "list_id": 0,
  "added": 0,
  "removed": 0,
  "already_in_list": [
    "user@example.com"
  ],
  "not_in_list": [
    "user@example.com"
  ],
  "not_found": [
    "user@example.com"
  ],
  "invalid_emails": [
    "string"
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Segments

Dynamic contact segments

List all segments (paginated)

GET
https://api.nitrosend.com/v1/my/segments

Parameters

pageinteger1query
perinteger<= 100100query

Response

200OKArray<Segment>

Segments

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List all segments (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/segments'
const response = await fetch('https://api.nitrosend.com/v1/my/segments', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/segments')
data = response.json()
200
[]

Create a segment

POST
https://api.nitrosend.com/v1/my/segments

filters must contain at least one condition. Empty filters ([], {} or a group with no conditions) would match every contact, so they are rejected with a 422 and validation_errors.filters. To reach every contact, target the All contacts audience instead of a segment.

Body

application/json
namestringrequired
filtersSegmentFilterExpressionrequired

Response

201CreatedSegment

Segment created

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create a segment
curl -X POST 'https://api.nitrosend.com/v1/my/segments' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/segments', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string"
}

response = requests.post('https://api.nitrosend.com/v1/my/segments', json=payload)
data = response.json()
Request Body
{
  "name": "string"
}
422
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get a segment

GET
https://api.nitrosend.com/v1/my/segments/{id}

Parameters

idintegerrequiredpath

Response

200OKSegment

Segment

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get a segment
curl -X GET 'https://api.nitrosend.com/v1/my/segments/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/segments/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/segments/{id}')
data = response.json()
404
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Delete a segment

DELETE
https://api.nitrosend.com/v1/my/segments/{id}

Parameters

idintegerrequiredpath

Response

200OKSegment

Deleted segment

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Delete a segment
curl -X DELETE 'https://api.nitrosend.com/v1/my/segments/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/segments/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/segments/{id}')
data = response.json()

Update a segment

PATCH
https://api.nitrosend.com/v1/my/segments/{id}

An update cannot remove every filter condition from a segment that has conditions; that returns a 422 with validation_errors.filters. Segments stored without conditions before this rule can still be renamed or re-saved with empty filters.

Body

application/json
namestring
filtersSegmentFilterExpression

Parameters

idintegerrequiredpath

Response

200OKSegment

Updated segment

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update a segment
curl -X PATCH 'https://api.nitrosend.com/v1/my/segments/{id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/segments/{id}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string"
}

response = requests.patch('https://api.nitrosend.com/v1/my/segments/{id}', json=payload)
data = response.json()
Request Body
{
  "name": "string"
}
422
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Count contacts matching filters

POST
https://api.nitrosend.com/v1/my/segments/count

Preview how many contacts match a set of segment filters without creating or saving a segment.

Body

application/json
filtersSegmentFilterExpression

Response

200OKobject

Contact count

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Count contacts matching filters
curl -X POST 'https://api.nitrosend.com/v1/my/segments/count' \
  -H 'Content-Type: application/json' \
  -d '{}'
const response = await fetch('https://api.nitrosend.com/v1/my/segments/count', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
});

const data = await response.json();
import requests

payload = {}

response = requests.post('https://api.nitrosend.com/v1/my/segments/count', json=payload)
data = response.json()
Request Body
{}
{
  "count": 0
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Preview contacts matching filters

POST
https://api.nitrosend.com/v1/my/segments/preview

Preview a prospective segment without saving it. Returns a live count, a bounded contact sample, and bounded overlap with existing segments. Invalid filters fail closed with invalid_filter.

Body

application/json
filtersSegmentFilterExpression

Response

200OKSegmentPreview

Segment preview

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Preview contacts matching filters
curl -X POST 'https://api.nitrosend.com/v1/my/segments/preview' \
  -H 'Content-Type: application/json' \
  -d '{}'
const response = await fetch('https://api.nitrosend.com/v1/my/segments/preview', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
});

const data = await response.json();
import requests

payload = {}

response = requests.post('https://api.nitrosend.com/v1/my/segments/preview', json=payload)
data = response.json()
Request Body
{}
{
  "count": 0,
  "sample": [
    {
      "id": 0,
      "email": "string",
      "name": "string"
    }
  ],
  "overlap": [
    {
      "segment_id": 0,
      "name": "string",
      "overlap_count": 0
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Campaigns

Email and SMS campaigns

List campaigns (paginated)

GET
https://api.nitrosend.com/v1/my/campaigns

Parameters

pageinteger1query
limitinteger<= 10025query

Response

200OKArray<Campaign>

Paginated campaigns

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List campaigns (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/campaigns'
const response = await fetch('https://api.nitrosend.com/v1/my/campaigns', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/campaigns')
data = response.json()
200
[
  {
    "id": 0,
    "account_id": 0,
    "brand_id": 0,
    "status": "draft",
    "approval_state": "string",
    "draft_revision_id": 0,
    "draft_revision_digest": "string",
    "draft_approval_state": "pending_review",
    "active_revision_id": 0,
    "active_revision_digest": "string",
    "has_unpublished_changes": true,
    "channel": "email",
    "name": "string",
    "data": {},
    "scheduled_at": "2024-01-15T09:30:00Z",
    "sent_count": 0,
    "dashboard_url": "https://example.com",
    "preview_url": "https://example.com",
    "recipient_snapshot": {
      "requested_recipients": 0,
      "dispatched_recipients": 0,
      "blocked_recipients": 0,
      "requested_send_units": 0,
      "dispatched_send_units": 0,
      "units_per_recipient": 0,
      "send_token": "string",
      "started_at": "2024-01-15T09:30:00Z",
      "completed_at": "2024-01-15T09:30:00Z"
    },
    "last_send_recipients": 0,
    "delivery": {
      "capacity_recovery": {
        "state": "approaching",
        "reason_code": "sending_capacity_warning",
        "blocking_control": "commercial_capacity",
        "usage_percent": 0,
        "requested_quantity": 0,
        "label": "string",
        "detail": "string",
        "capacity": {
          "source": "plan",
          "window_seconds": 86400,
          "status": "known",
          "limit": 0,
          "reserved": 0,
          "accepted": 0,
          "provider_unknown": 0,
          "remaining": 0
        },
        "upgrade_url": "https://example.com",
        "retry_at": "2024-01-15T09:30:00Z",
        "recovery_action": {
          "type": "upgrade_plan",
          "label": "string",
          "detail": "string",
          "url": "https://example.com",
          "required_role": "account_owner_or_admin"
        },
        "recovery_actions": [
          {
            "type": "upgrade_plan",
            "label": "string",
            "detail": "string",
            "url": "https://example.com",
            "required_role": "account_owner_or_admin"
          }
        ],
        "owner_action": {
          "type": "upgrade_plan",
          "label": "string",
          "detail": "string",
          "url": "https://example.com",
          "required_role": "account_owner_or_admin"
        }
      },
      "campaign_send_token": "string",
      "status": "sending",
      "recipients": 0,
      "sent": 0,
      "failed": 0,
      "pending": 0
    },
    "engagement": {
      "sent": 0,
      "opens": 0,
      "total_opens": 0,
      "open_rate": 0,
      "account": {
        "sent": 0,
        "opens": 0,
        "total_opens": 0,
        "open_rate": 0
      }
    },
    "revenue": {
      "attribution_label": "Attributed revenue. Last click, 7-day window.",
      "currency": "string",
      "mixed_currency": true,
      "attributed_revenue_cents": 0,
      "delivered": 0,
      "attributed_orders": 0,
      "revenue_per_recipient": 0,
      "conversion_rate": 0,
      "attributed_aov": 0,
      "message_breakdown": [
        {
          "message_id": 0,
          "subject": "string",
          "sent_at": "2024-01-15T09:30:00Z",
          "currency": "string",
          "mixed_currency": true,
          "delivered": 0,
          "attributed_orders": 0,
          "attributed_revenue_cents": 0,
          "revenue_per_recipient": 0,
          "conversion_rate": 0,
          "attributed_aov": 0
        }
      ]
    },
    "editable": true,
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z",
    "trigger": {
      "id": 0,
      "flow_id": 0,
      "event": "string",
      "audience_type": "lists",
      "segment_id": 0,
      "contact_list_id": 0,
      "contact_list_ids": [
        0
      ],
      "exclude_segment_ids": [
        0
      ],
      "exclude_contact_list_ids": [
        0
      ],
      "data": {},
      "triggered_count": 0,
      "last_triggered_at": "2024-01-15T09:30:00Z",
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    },
    "template": {
      "id": 0,
      "name": "string",
      "flow_id": 0,
      "action_id": 0,
      "version": 0,
      "subject": "string",
      "body": "string",
      "preheader": "string",
      "from_name": "string",
      "from_email": "string",
      "reply_to": "string",
      "design": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      },
      "variables": {},
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      },
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    },
    "templates": [
      {
        "id": 0,
        "name": "string",
        "flow_id": 0,
        "action_id": 0,
        "version": 0,
        "subject": "string",
        "body": "string",
        "preheader": "string",
        "from_name": "string",
        "from_email": "string",
        "reply_to": "string",
        "design": {
          "version": 1,
          "sections": [
            {
              "type": "header",
              "props": {},
              "styles": {
                "background_color": "string",
                "section_background_color": "string",
                "padding": "string",
                "align": "left",
                "scale": "display",
                "font_size": 0,
                "text_color": "string",
                "shape": "square",
                "remove_gap": true,
                "border_radius": 0
              }
            }
          ],
          "theme": {
            "brand_color": "string",
            "bg_color": "string",
            "text_color": "string",
            "font_body": "string",
            "font_heading": "string",
            "heading_size": 0,
            "body_size": 0,
            "radius": 0,
            "spacing_density": "compact",
            "button_background_color": "string",
            "button_text_color": "string",
            "button_padding": "string",
            "logo_url": "string",
            "company_name": "string",
            "physical_address": "string",
            "social_links": [
              {
                "platform": "string",
                "url": "string"
              }
            ]
          }
        },
        "variables": {},
        "generation_provenance": {
          "state": "candidate",
          "event_id": 0,
          "candidate_locator": "string",
          "generated_slice_digest": "string",
          "acceptance_id": 0,
          "saved_authored_digest": "string",
          "edit_relation": "identical"
        },
        "created_at": "2024-01-15T09:30:00Z",
        "updated_at": "2024-01-15T09:30:00Z"
      }
    ]
  }
]

Create a campaign

POST
https://api.nitrosend.com/v1/my/campaigns

Body

application/json
namestringrequired
channelstringemailsmsemail

Response

201CreatedCampaign

Campaign created

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create a campaign
curl -X POST 'https://api.nitrosend.com/v1/my/campaigns' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string",
    "channel": "email"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/campaigns', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string",
      "channel": "email"
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string",
  "channel": "email"
}

response = requests.post('https://api.nitrosend.com/v1/my/campaigns', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "channel": "email"
}
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "status": "draft",
  "approval_state": "string",
  "draft_revision_id": 0,
  "draft_revision_digest": "string",
  "draft_approval_state": "pending_review",
  "active_revision_id": 0,
  "active_revision_digest": "string",
  "has_unpublished_changes": true,
  "channel": "email",
  "name": "string",
  "data": {},
  "scheduled_at": "2024-01-15T09:30:00Z",
  "sent_count": 0,
  "dashboard_url": "https://example.com",
  "preview_url": "https://example.com",
  "recipient_snapshot": {
    "requested_recipients": 0,
    "dispatched_recipients": 0,
    "blocked_recipients": 0,
    "requested_send_units": 0,
    "dispatched_send_units": 0,
    "units_per_recipient": 0,
    "send_token": "string",
    "started_at": "2024-01-15T09:30:00Z",
    "completed_at": "2024-01-15T09:30:00Z"
  },
  "last_send_recipients": 0,
  "delivery": {
    "capacity_recovery": {
      "state": "approaching",
      "reason_code": "sending_capacity_warning",
      "blocking_control": "commercial_capacity",
      "usage_percent": 0,
      "requested_quantity": 0,
      "label": "string",
      "detail": "string",
      "capacity": {
        "source": "plan",
        "window_seconds": 86400,
        "status": "known",
        "limit": 0,
        "reserved": 0,
        "accepted": 0,
        "provider_unknown": 0,
        "remaining": 0
      },
      "upgrade_url": "https://example.com",
      "retry_at": "2024-01-15T09:30:00Z",
      "recovery_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      },
      "recovery_actions": [
        {
          "type": "upgrade_plan",
          "label": "string",
          "detail": "string",
          "url": "https://example.com",
          "required_role": "account_owner_or_admin"
        }
      ],
      "owner_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    },
    "campaign_send_token": "string",
    "status": "sending",
    "recipients": 0,
    "sent": 0,
    "failed": 0,
    "pending": 0
  },
  "engagement": {
    "sent": 0,
    "opens": 0,
    "total_opens": 0,
    "open_rate": 0,
    "account": {
      "sent": 0,
      "opens": 0,
      "total_opens": 0,
      "open_rate": 0
    }
  },
  "revenue": {
    "attribution_label": "Attributed revenue. Last click, 7-day window.",
    "currency": "string",
    "mixed_currency": true,
    "attributed_revenue_cents": 0,
    "delivered": 0,
    "attributed_orders": 0,
    "revenue_per_recipient": 0,
    "conversion_rate": 0,
    "attributed_aov": 0,
    "message_breakdown": [
      {
        "message_id": 0,
        "subject": "string",
        "sent_at": "2024-01-15T09:30:00Z",
        "currency": "string",
        "mixed_currency": true,
        "delivered": 0,
        "attributed_orders": 0,
        "attributed_revenue_cents": 0,
        "revenue_per_recipient": 0,
        "conversion_rate": 0,
        "attributed_aov": 0
      }
    ]
  },
  "editable": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "trigger": {
    "id": 0,
    "flow_id": 0,
    "event": "string",
    "audience_type": "lists",
    "segment_id": 0,
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "exclude_segment_ids": [
      0
    ],
    "exclude_contact_list_ids": [
      0
    ],
    "data": {},
    "triggered_count": 0,
    "last_triggered_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "template": {
    "id": 0,
    "name": "string",
    "flow_id": 0,
    "action_id": 0,
    "version": 0,
    "subject": "string",
    "body": "string",
    "preheader": "string",
    "from_name": "string",
    "from_email": "string",
    "reply_to": "string",
    "design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    },
    "variables": {},
    "generation_provenance": {
      "state": "candidate",
      "event_id": 0,
      "candidate_locator": "string",
      "generated_slice_digest": "string",
      "acceptance_id": 0,
      "saved_authored_digest": "string",
      "edit_relation": "identical"
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "templates": [
    {
      "id": 0,
      "name": "string",
      "flow_id": 0,
      "action_id": 0,
      "version": 0,
      "subject": "string",
      "body": "string",
      "preheader": "string",
      "from_name": "string",
      "from_email": "string",
      "reply_to": "string",
      "design": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      },
      "variables": {},
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      },
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get a campaign

GET
https://api.nitrosend.com/v1/my/campaigns/{id}

Parameters

idintegerrequiredpath

Response

200OKCampaign

Campaign with trigger, template, and templates

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get a campaign
curl -X GET 'https://api.nitrosend.com/v1/my/campaigns/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/campaigns/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/campaigns/{id}')
data = response.json()
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "status": "draft",
  "approval_state": "string",
  "draft_revision_id": 0,
  "draft_revision_digest": "string",
  "draft_approval_state": "pending_review",
  "active_revision_id": 0,
  "active_revision_digest": "string",
  "has_unpublished_changes": true,
  "channel": "email",
  "name": "string",
  "data": {},
  "scheduled_at": "2024-01-15T09:30:00Z",
  "sent_count": 0,
  "dashboard_url": "https://example.com",
  "preview_url": "https://example.com",
  "recipient_snapshot": {
    "requested_recipients": 0,
    "dispatched_recipients": 0,
    "blocked_recipients": 0,
    "requested_send_units": 0,
    "dispatched_send_units": 0,
    "units_per_recipient": 0,
    "send_token": "string",
    "started_at": "2024-01-15T09:30:00Z",
    "completed_at": "2024-01-15T09:30:00Z"
  },
  "last_send_recipients": 0,
  "delivery": {
    "capacity_recovery": {
      "state": "approaching",
      "reason_code": "sending_capacity_warning",
      "blocking_control": "commercial_capacity",
      "usage_percent": 0,
      "requested_quantity": 0,
      "label": "string",
      "detail": "string",
      "capacity": {
        "source": "plan",
        "window_seconds": 86400,
        "status": "known",
        "limit": 0,
        "reserved": 0,
        "accepted": 0,
        "provider_unknown": 0,
        "remaining": 0
      },
      "upgrade_url": "https://example.com",
      "retry_at": "2024-01-15T09:30:00Z",
      "recovery_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      },
      "recovery_actions": [
        {
          "type": "upgrade_plan",
          "label": "string",
          "detail": "string",
          "url": "https://example.com",
          "required_role": "account_owner_or_admin"
        }
      ],
      "owner_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    },
    "campaign_send_token": "string",
    "status": "sending",
    "recipients": 0,
    "sent": 0,
    "failed": 0,
    "pending": 0
  },
  "engagement": {
    "sent": 0,
    "opens": 0,
    "total_opens": 0,
    "open_rate": 0,
    "account": {
      "sent": 0,
      "opens": 0,
      "total_opens": 0,
      "open_rate": 0
    }
  },
  "revenue": {
    "attribution_label": "Attributed revenue. Last click, 7-day window.",
    "currency": "string",
    "mixed_currency": true,
    "attributed_revenue_cents": 0,
    "delivered": 0,
    "attributed_orders": 0,
    "revenue_per_recipient": 0,
    "conversion_rate": 0,
    "attributed_aov": 0,
    "message_breakdown": [
      {
        "message_id": 0,
        "subject": "string",
        "sent_at": "2024-01-15T09:30:00Z",
        "currency": "string",
        "mixed_currency": true,
        "delivered": 0,
        "attributed_orders": 0,
        "attributed_revenue_cents": 0,
        "revenue_per_recipient": 0,
        "conversion_rate": 0,
        "attributed_aov": 0
      }
    ]
  },
  "editable": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "trigger": {
    "id": 0,
    "flow_id": 0,
    "event": "string",
    "audience_type": "lists",
    "segment_id": 0,
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "exclude_segment_ids": [
      0
    ],
    "exclude_contact_list_ids": [
      0
    ],
    "data": {},
    "triggered_count": 0,
    "last_triggered_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "template": {
    "id": 0,
    "name": "string",
    "flow_id": 0,
    "action_id": 0,
    "version": 0,
    "subject": "string",
    "body": "string",
    "preheader": "string",
    "from_name": "string",
    "from_email": "string",
    "reply_to": "string",
    "design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    },
    "variables": {},
    "generation_provenance": {
      "state": "candidate",
      "event_id": 0,
      "candidate_locator": "string",
      "generated_slice_digest": "string",
      "acceptance_id": 0,
      "saved_authored_digest": "string",
      "edit_relation": "identical"
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "templates": [
    {
      "id": 0,
      "name": "string",
      "flow_id": 0,
      "action_id": 0,
      "version": 0,
      "subject": "string",
      "body": "string",
      "preheader": "string",
      "from_name": "string",
      "from_email": "string",
      "reply_to": "string",
      "design": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      },
      "variables": {},
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      },
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Delete a campaign

DELETE
https://api.nitrosend.com/v1/my/campaigns/{id}

Parameters

idintegerrequiredpath

Response

200OKCampaign

Deleted campaign

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Delete a campaign
curl -X DELETE 'https://api.nitrosend.com/v1/my/campaigns/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/campaigns/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/campaigns/{id}')
data = response.json()
200
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "status": "draft",
  "approval_state": "string",
  "draft_revision_id": 0,
  "draft_revision_digest": "string",
  "draft_approval_state": "pending_review",
  "active_revision_id": 0,
  "active_revision_digest": "string",
  "has_unpublished_changes": true,
  "channel": "email",
  "name": "string",
  "data": {},
  "scheduled_at": "2024-01-15T09:30:00Z",
  "sent_count": 0,
  "dashboard_url": "https://example.com",
  "preview_url": "https://example.com",
  "recipient_snapshot": {
    "requested_recipients": 0,
    "dispatched_recipients": 0,
    "blocked_recipients": 0,
    "requested_send_units": 0,
    "dispatched_send_units": 0,
    "units_per_recipient": 0,
    "send_token": "string",
    "started_at": "2024-01-15T09:30:00Z",
    "completed_at": "2024-01-15T09:30:00Z"
  },
  "last_send_recipients": 0,
  "delivery": {
    "capacity_recovery": {
      "state": "approaching",
      "reason_code": "sending_capacity_warning",
      "blocking_control": "commercial_capacity",
      "usage_percent": 0,
      "requested_quantity": 0,
      "label": "string",
      "detail": "string",
      "capacity": {
        "source": "plan",
        "window_seconds": 86400,
        "status": "known",
        "limit": 0,
        "reserved": 0,
        "accepted": 0,
        "provider_unknown": 0,
        "remaining": 0
      },
      "upgrade_url": "https://example.com",
      "retry_at": "2024-01-15T09:30:00Z",
      "recovery_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      },
      "recovery_actions": [
        {
          "type": "upgrade_plan",
          "label": "string",
          "detail": "string",
          "url": "https://example.com",
          "required_role": "account_owner_or_admin"
        }
      ],
      "owner_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    },
    "campaign_send_token": "string",
    "status": "sending",
    "recipients": 0,
    "sent": 0,
    "failed": 0,
    "pending": 0
  },
  "engagement": {
    "sent": 0,
    "opens": 0,
    "total_opens": 0,
    "open_rate": 0,
    "account": {
      "sent": 0,
      "opens": 0,
      "total_opens": 0,
      "open_rate": 0
    }
  },
  "revenue": {
    "attribution_label": "Attributed revenue. Last click, 7-day window.",
    "currency": "string",
    "mixed_currency": true,
    "attributed_revenue_cents": 0,
    "delivered": 0,
    "attributed_orders": 0,
    "revenue_per_recipient": 0,
    "conversion_rate": 0,
    "attributed_aov": 0,
    "message_breakdown": [
      {
        "message_id": 0,
        "subject": "string",
        "sent_at": "2024-01-15T09:30:00Z",
        "currency": "string",
        "mixed_currency": true,
        "delivered": 0,
        "attributed_orders": 0,
        "attributed_revenue_cents": 0,
        "revenue_per_recipient": 0,
        "conversion_rate": 0,
        "attributed_aov": 0
      }
    ]
  },
  "editable": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "trigger": {
    "id": 0,
    "flow_id": 0,
    "event": "string",
    "audience_type": "lists",
    "segment_id": 0,
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "exclude_segment_ids": [
      0
    ],
    "exclude_contact_list_ids": [
      0
    ],
    "data": {},
    "triggered_count": 0,
    "last_triggered_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "template": {
    "id": 0,
    "name": "string",
    "flow_id": 0,
    "action_id": 0,
    "version": 0,
    "subject": "string",
    "body": "string",
    "preheader": "string",
    "from_name": "string",
    "from_email": "string",
    "reply_to": "string",
    "design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    },
    "variables": {},
    "generation_provenance": {
      "state": "candidate",
      "event_id": 0,
      "candidate_locator": "string",
      "generated_slice_digest": "string",
      "acceptance_id": 0,
      "saved_authored_digest": "string",
      "edit_relation": "identical"
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "templates": [
    {
      "id": 0,
      "name": "string",
      "flow_id": 0,
      "action_id": 0,
      "version": 0,
      "subject": "string",
      "body": "string",
      "preheader": "string",
      "from_name": "string",
      "from_email": "string",
      "reply_to": "string",
      "design": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      },
      "variables": {},
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      },
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}

Update a campaign

PATCH
https://api.nitrosend.com/v1/my/campaigns/{id}

Updates the campaign. When the campaign is no longer editable (see the editable field on the Campaign schema — false for live/paused/ completed/cancelled/archived, and for scheduled campaigns within 5 minutes of their send time), only name-only payloads and status transitions (Resume, Cancel) are accepted. Any other attribute returns 422 with error_code: "campaign_locked". Use the /duplicate endpoint to fork a sent campaign into a new draft.

Body

application/json
namestring
statusstring
channelstringemailsms
scheduled_atstring<date-time> | null
trigger_attributesobject
Show child attributes
eventstring
audience_typestring | nulllistssegmentall_contacts

Explicit campaign audience target. Use all_contacts only for deliberate all-subscribed-contact sends.

contact_list_idinteger | nulldeprecated
contact_list_idsArray<integer>
segment_idinteger | null
exclude_segment_idsArray<integer>

Segment IDs whose matching contacts are excluded; pass [] to clear

exclude_contact_list_idsArray<integer>

Contact list IDs whose members are excluded; pass [] to clear

dataobject
template_attributesobject
Show child attributes
if_versionintegerrequired

Required optimistic concurrency token for template content writes. Use the current template.version. A stale value returns 409 with current_version and expected_version.

subjectstring
bodystring
preheaderstring
from_namestring
from_emailstring<email>
reply_tostring<email>
generation_provenanceGenerationProvenance

Candidate-bound generation evidence. Save endpoints accept only state: candidate values returned by the generation endpoint. Resource responses may return state: accepted as read-only history.

Show child attributes
statestringcandidateacceptedrequired
event_idintegerrequired
candidate_locatorstring
generated_slice_digeststring
acceptance_idinteger
saved_authored_digeststring
edit_relationstringidenticaledited
designEmailDesign

Email template design document

Show child attributes
versioninteger>= 1
sectionsArray<EmailSection>
Show child attributes
typestringheaderherotextimagebuttoncolumnsproductproductsgallerysocialdividerspacerfooterrequired
propsobject

Section-specific properties (see email component spec)

stylesobject
Show child attributes
background_colorstring
section_background_colorstring
paddingstring
alignstringleftcenterright
scalestringdisplayposter
font_sizeinteger
text_colorstring
shapestringsquareroundedarchcircle
remove_gapboolean
border_radiusinteger
themeobject

Theme overrides merged on top of brand theme

Show child attributes
brand_colorstring
bg_colorstring
text_colorstring
font_bodystring
font_headingstring
heading_sizeinteger
body_sizeinteger
radiusinteger
spacing_densitystringcompactnormalspacious
button_background_colorstring
button_text_colorstring
button_paddingstring
logo_urlstring
company_namestring
physical_addressstring
social_linksArray<object>
Show child attributes
platformstring
urlstring

Parameters

idintegerrequiredpath

Response

200OKCampaign

Updated campaign

409ConflictError

Template version conflict

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update a campaign
curl -X PATCH 'https://api.nitrosend.com/v1/my/campaigns/{id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string",
    "status": "string",
    "channel": "email",
    "scheduled_at": "2024-01-15T09:30:00Z",
    "trigger_attributes": {
      "event": "string",
      "audience_type": "lists",
      "contact_list_id": 0,
      "contact_list_ids": [
        0
      ],
      "segment_id": 0,
      "exclude_segment_ids": [
        0
      ],
      "exclude_contact_list_ids": [
        0
      ],
      "data": {}
    },
    "template_attributes": {
      "if_version": 0,
      "subject": "string",
      "body": "string",
      "preheader": "string",
      "from_name": "string",
      "from_email": "user@example.com",
      "reply_to": "user@example.com",
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      },
      "design": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      }
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/campaigns/{id}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string",
      "status": "string",
      "channel": "email",
      "scheduled_at": "2024-01-15T09:30:00Z",
      "trigger_attributes": {
        "event": "string",
        "audience_type": "lists",
        "contact_list_id": 0,
        "contact_list_ids": [
          0
        ],
        "segment_id": 0,
        "exclude_segment_ids": [
          0
        ],
        "exclude_contact_list_ids": [
          0
        ],
        "data": {}
      },
      "template_attributes": {
        "if_version": 0,
        "subject": "string",
        "body": "string",
        "preheader": "string",
        "from_name": "string",
        "from_email": "user@example.com",
        "reply_to": "user@example.com",
        "generation_provenance": {
          "state": "candidate",
          "event_id": 0,
          "candidate_locator": "string",
          "generated_slice_digest": "string",
          "acceptance_id": 0,
          "saved_authored_digest": "string",
          "edit_relation": "identical"
        },
        "design": {
          "version": 1,
          "sections": [
            {
              "type": "header",
              "props": {},
              "styles": {
                "background_color": "string",
                "section_background_color": "string",
                "padding": "string",
                "align": "left",
                "scale": "display",
                "font_size": 0,
                "text_color": "string",
                "shape": "square",
                "remove_gap": true,
                "border_radius": 0
              }
            }
          ],
          "theme": {
            "brand_color": "string",
            "bg_color": "string",
            "text_color": "string",
            "font_body": "string",
            "font_heading": "string",
            "heading_size": 0,
            "body_size": 0,
            "radius": 0,
            "spacing_density": "compact",
            "button_background_color": "string",
            "button_text_color": "string",
            "button_padding": "string",
            "logo_url": "string",
            "company_name": "string",
            "physical_address": "string",
            "social_links": [
              {
                "platform": "string",
                "url": "string"
              }
            ]
          }
        }
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string",
  "status": "string",
  "channel": "email",
  "scheduled_at": "2024-01-15T09:30:00Z",
  "trigger_attributes": {
    "event": "string",
    "audience_type": "lists",
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "segment_id": 0,
    "exclude_segment_ids": [
      0
    ],
    "exclude_contact_list_ids": [
      0
    ],
    "data": {}
  },
  "template_attributes": {
    "if_version": 0,
    "subject": "string",
    "body": "string",
    "preheader": "string",
    "from_name": "string",
    "from_email": "user@example.com",
    "reply_to": "user@example.com",
    "generation_provenance": {
      "state": "candidate",
      "event_id": 0,
      "candidate_locator": "string",
      "generated_slice_digest": "string",
      "acceptance_id": 0,
      "saved_authored_digest": "string",
      "edit_relation": "identical"
    },
    "design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": True,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    }
  }
}

response = requests.patch('https://api.nitrosend.com/v1/my/campaigns/{id}', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "status": "string",
  "channel": "email",
  "scheduled_at": "2024-01-15T09:30:00Z",
  "trigger_attributes": {
    "event": "string",
    "audience_type": "lists",
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "segment_id": 0,
    "exclude_segment_ids": [
      0
    ],
    "exclude_contact_list_ids": [
      0
    ],
    "data": {}
  },
  "template_attributes": {
    "if_version": 0,
    "subject": "string",
    "body": "string",
    "preheader": "string",
    "from_name": "string",
    "from_email": "user@example.com",
    "reply_to": "user@example.com",
    "generation_provenance": {
      "state": "candidate",
      "event_id": 0,
      "candidate_locator": "string",
      "generated_slice_digest": "string",
      "acceptance_id": 0,
      "saved_authored_digest": "string",
      "edit_relation": "identical"
    },
    "design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    }
  }
}
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "status": "draft",
  "approval_state": "string",
  "draft_revision_id": 0,
  "draft_revision_digest": "string",
  "draft_approval_state": "pending_review",
  "active_revision_id": 0,
  "active_revision_digest": "string",
  "has_unpublished_changes": true,
  "channel": "email",
  "name": "string",
  "data": {},
  "scheduled_at": "2024-01-15T09:30:00Z",
  "sent_count": 0,
  "dashboard_url": "https://example.com",
  "preview_url": "https://example.com",
  "recipient_snapshot": {
    "requested_recipients": 0,
    "dispatched_recipients": 0,
    "blocked_recipients": 0,
    "requested_send_units": 0,
    "dispatched_send_units": 0,
    "units_per_recipient": 0,
    "send_token": "string",
    "started_at": "2024-01-15T09:30:00Z",
    "completed_at": "2024-01-15T09:30:00Z"
  },
  "last_send_recipients": 0,
  "delivery": {
    "capacity_recovery": {
      "state": "approaching",
      "reason_code": "sending_capacity_warning",
      "blocking_control": "commercial_capacity",
      "usage_percent": 0,
      "requested_quantity": 0,
      "label": "string",
      "detail": "string",
      "capacity": {
        "source": "plan",
        "window_seconds": 86400,
        "status": "known",
        "limit": 0,
        "reserved": 0,
        "accepted": 0,
        "provider_unknown": 0,
        "remaining": 0
      },
      "upgrade_url": "https://example.com",
      "retry_at": "2024-01-15T09:30:00Z",
      "recovery_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      },
      "recovery_actions": [
        {
          "type": "upgrade_plan",
          "label": "string",
          "detail": "string",
          "url": "https://example.com",
          "required_role": "account_owner_or_admin"
        }
      ],
      "owner_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    },
    "campaign_send_token": "string",
    "status": "sending",
    "recipients": 0,
    "sent": 0,
    "failed": 0,
    "pending": 0
  },
  "engagement": {
    "sent": 0,
    "opens": 0,
    "total_opens": 0,
    "open_rate": 0,
    "account": {
      "sent": 0,
      "opens": 0,
      "total_opens": 0,
      "open_rate": 0
    }
  },
  "revenue": {
    "attribution_label": "Attributed revenue. Last click, 7-day window.",
    "currency": "string",
    "mixed_currency": true,
    "attributed_revenue_cents": 0,
    "delivered": 0,
    "attributed_orders": 0,
    "revenue_per_recipient": 0,
    "conversion_rate": 0,
    "attributed_aov": 0,
    "message_breakdown": [
      {
        "message_id": 0,
        "subject": "string",
        "sent_at": "2024-01-15T09:30:00Z",
        "currency": "string",
        "mixed_currency": true,
        "delivered": 0,
        "attributed_orders": 0,
        "attributed_revenue_cents": 0,
        "revenue_per_recipient": 0,
        "conversion_rate": 0,
        "attributed_aov": 0
      }
    ]
  },
  "editable": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "trigger": {
    "id": 0,
    "flow_id": 0,
    "event": "string",
    "audience_type": "lists",
    "segment_id": 0,
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "exclude_segment_ids": [
      0
    ],
    "exclude_contact_list_ids": [
      0
    ],
    "data": {},
    "triggered_count": 0,
    "last_triggered_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "template": {
    "id": 0,
    "name": "string",
    "flow_id": 0,
    "action_id": 0,
    "version": 0,
    "subject": "string",
    "body": "string",
    "preheader": "string",
    "from_name": "string",
    "from_email": "string",
    "reply_to": "string",
    "design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    },
    "variables": {},
    "generation_provenance": {
      "state": "candidate",
      "event_id": 0,
      "candidate_locator": "string",
      "generated_slice_digest": "string",
      "acceptance_id": 0,
      "saved_authored_digest": "string",
      "edit_relation": "identical"
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "templates": [
    {
      "id": 0,
      "name": "string",
      "flow_id": 0,
      "action_id": 0,
      "version": 0,
      "subject": "string",
      "body": "string",
      "preheader": "string",
      "from_name": "string",
      "from_email": "string",
      "reply_to": "string",
      "design": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      },
      "variables": {},
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      },
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Duplicate a campaign

POST
https://api.nitrosend.com/v1/my/campaigns/{id}/duplicate

Creates a new draft campaign that copies the source's audience (trigger.audience_type, contact_list_ids, segment_id, exclude_segment_ids, exclude_contact_list_ids) and template content (design, subject, preheader, body, from_name, from_email, reply_to). Resets status to draft, approval_state to pending_review, scheduled_at to null, and trigger.event to manual. Works on any status — this is how clients fork a sent campaign into a new draft. Sessions, activities, approvals, and metrics are not copied.

Pass cancel_source: true to atomically cancel the source campaign in the same transaction as the duplicate — useful for 'cancel and duplicate' flows on paused campaigns.

Body

application/json
cancel_sourcebooleanfalse

When true, cancels the source campaign in the same DB transaction as the duplicate creation.

Parameters

idintegerrequiredpath

Response

201CreatedCampaign

New draft campaign

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Duplicate a campaign
curl -X POST 'https://api.nitrosend.com/v1/my/campaigns/{id}/duplicate' \
  -H 'Content-Type: application/json' \
  -d '{
    "cancel_source": false
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/campaigns/{id}/duplicate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "cancel_source": false
    }),
});

const data = await response.json();
import requests

payload = {
  "cancel_source": False
}

response = requests.post('https://api.nitrosend.com/v1/my/campaigns/{id}/duplicate', json=payload)
data = response.json()
Request Body
{
  "cancel_source": false
}
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "status": "draft",
  "approval_state": "string",
  "draft_revision_id": 0,
  "draft_revision_digest": "string",
  "draft_approval_state": "pending_review",
  "active_revision_id": 0,
  "active_revision_digest": "string",
  "has_unpublished_changes": true,
  "channel": "email",
  "name": "string",
  "data": {},
  "scheduled_at": "2024-01-15T09:30:00Z",
  "sent_count": 0,
  "dashboard_url": "https://example.com",
  "preview_url": "https://example.com",
  "recipient_snapshot": {
    "requested_recipients": 0,
    "dispatched_recipients": 0,
    "blocked_recipients": 0,
    "requested_send_units": 0,
    "dispatched_send_units": 0,
    "units_per_recipient": 0,
    "send_token": "string",
    "started_at": "2024-01-15T09:30:00Z",
    "completed_at": "2024-01-15T09:30:00Z"
  },
  "last_send_recipients": 0,
  "delivery": {
    "capacity_recovery": {
      "state": "approaching",
      "reason_code": "sending_capacity_warning",
      "blocking_control": "commercial_capacity",
      "usage_percent": 0,
      "requested_quantity": 0,
      "label": "string",
      "detail": "string",
      "capacity": {
        "source": "plan",
        "window_seconds": 86400,
        "status": "known",
        "limit": 0,
        "reserved": 0,
        "accepted": 0,
        "provider_unknown": 0,
        "remaining": 0
      },
      "upgrade_url": "https://example.com",
      "retry_at": "2024-01-15T09:30:00Z",
      "recovery_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      },
      "recovery_actions": [
        {
          "type": "upgrade_plan",
          "label": "string",
          "detail": "string",
          "url": "https://example.com",
          "required_role": "account_owner_or_admin"
        }
      ],
      "owner_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    },
    "campaign_send_token": "string",
    "status": "sending",
    "recipients": 0,
    "sent": 0,
    "failed": 0,
    "pending": 0
  },
  "engagement": {
    "sent": 0,
    "opens": 0,
    "total_opens": 0,
    "open_rate": 0,
    "account": {
      "sent": 0,
      "opens": 0,
      "total_opens": 0,
      "open_rate": 0
    }
  },
  "revenue": {
    "attribution_label": "Attributed revenue. Last click, 7-day window.",
    "currency": "string",
    "mixed_currency": true,
    "attributed_revenue_cents": 0,
    "delivered": 0,
    "attributed_orders": 0,
    "revenue_per_recipient": 0,
    "conversion_rate": 0,
    "attributed_aov": 0,
    "message_breakdown": [
      {
        "message_id": 0,
        "subject": "string",
        "sent_at": "2024-01-15T09:30:00Z",
        "currency": "string",
        "mixed_currency": true,
        "delivered": 0,
        "attributed_orders": 0,
        "attributed_revenue_cents": 0,
        "revenue_per_recipient": 0,
        "conversion_rate": 0,
        "attributed_aov": 0
      }
    ]
  },
  "editable": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "trigger": {
    "id": 0,
    "flow_id": 0,
    "event": "string",
    "audience_type": "lists",
    "segment_id": 0,
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "exclude_segment_ids": [
      0
    ],
    "exclude_contact_list_ids": [
      0
    ],
    "data": {},
    "triggered_count": 0,
    "last_triggered_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "template": {
    "id": 0,
    "name": "string",
    "flow_id": 0,
    "action_id": 0,
    "version": 0,
    "subject": "string",
    "body": "string",
    "preheader": "string",
    "from_name": "string",
    "from_email": "string",
    "reply_to": "string",
    "design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    },
    "variables": {},
    "generation_provenance": {
      "state": "candidate",
      "event_id": 0,
      "candidate_locator": "string",
      "generated_slice_digest": "string",
      "acceptance_id": 0,
      "saved_authored_digest": "string",
      "edit_relation": "identical"
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "templates": [
    {
      "id": 0,
      "name": "string",
      "flow_id": 0,
      "action_id": 0,
      "version": 0,
      "subject": "string",
      "body": "string",
      "preheader": "string",
      "from_name": "string",
      "from_email": "string",
      "reply_to": "string",
      "design": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      },
      "variables": {},
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      },
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Render a campaign email to HTML

GET
https://api.nitrosend.com/v1/my/campaigns/{id}/render

Renders the campaign's current template through the shared preview renderer.

Parameters

idintegerrequiredpath

Response

200OKobject

Rendered HTML

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Render a campaign email to HTML
curl -X GET 'https://api.nitrosend.com/v1/my/campaigns/{id}/render'
const response = await fetch('https://api.nitrosend.com/v1/my/campaigns/{id}/render', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/campaigns/{id}/render')
data = response.json()
{
  "html": "string"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Read saved campaign readiness and capacity guidance

GET
https://api.nitrosend.com/v1/my/campaigns/{id}/readiness

Read-only structural checks and the deduplicated saved audience count. Capacity warnings are informational, not approval or admission gates. Save pending draft changes before requesting this projection.

Parameters

idintegerrequiredpath

Response

200OKobject

Structural readiness with optional capacity guidance

404Not FoundError

Resource not found

503Service UnavailableError

A read did not finish within the request's database time limit (error_code: query_timeout). Nothing was changed; retry after the Retry-After interval. Any GET can return this.

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Read saved campaign readiness and capacity guidance
curl -X GET 'https://api.nitrosend.com/v1/my/campaigns/{id}/readiness'
const response = await fetch('https://api.nitrosend.com/v1/my/campaigns/{id}/readiness', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/campaigns/{id}/readiness')
data = response.json()
{
  "ready": true,
  "authority": "structural_readiness_only",
  "note": "string",
  "checks": [
    {
      "name": "string",
      "passed": true,
      "message": "string",
      "audience_count": 0
    }
  ],
  "blocking_issues": [
    "string"
  ],
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Get current campaign delivery progress

GET
https://api.nitrosend.com/v1/my/campaigns/{id}/delivery

Polls the current campaign send using the same Campaign::SendProgress payload exposed on the campaign serializer. Active sends return status: "sending" with poll_after_seconds; terminal sends return status: "completed" or status: "paused" when a deliverability guard stopped the active send. Campaigns that have not started delivery return status: "not_started". Polling also refreshes server-side progress: queued reservations older than 15 minutes are marked failed before the response is returned, so failed/pending can change on a poll even when no provider webhook has arrived.

Parameters

idintegerrequiredpath

Response

200OKCampaignDeliveryProgress

Current campaign delivery progress

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get current campaign delivery progress
curl -X GET 'https://api.nitrosend.com/v1/my/campaigns/{id}/delivery'
const response = await fetch('https://api.nitrosend.com/v1/my/campaigns/{id}/delivery', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/campaigns/{id}/delivery')
data = response.json()
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "campaign_send_token": "string",
  "status": "not_started",
  "recipients": 0,
  "sent": 0,
  "failed": 0,
  "pending": 0,
  "terminal": true,
  "poll_after_seconds": 0
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Send a test email for a campaign

POST
https://api.nitrosend.com/v1/my/campaigns/{id}/send_test

Thin adapter over the same test-send service used by template tests. Use contact_id to send directly to a contact, or sample_contact_id to personalize explicit test recipients without sending to that contact. The two contact parameters are mutually exclusive. Test emails go to the account's own people (owner, members, an active managing account's people) and to addresses at the account's verified domains. Up to 10 other addresses per 30 days are allowed; past that, each refused recipient is reported in results with status: failed and the reason in error, and the other recipients still receive the test. Supply one fresh Idempotency-Key for each user-initiated send and reuse that exact key for transport retries.

Body

application/json
emailstring<email>
emailsArray<string>
send_test_toArray<string>
contact_idinteger
sample_contact_idinteger

Contact whose projected data personalizes the test without changing the test recipient.

Parameters

idintegerrequiredpath
Idempotency-Keystringrequiredheader

Response

200OKobject

Test email sent

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Send a test email for a campaign
curl -X POST 'https://api.nitrosend.com/v1/my/campaigns/{id}/send_test' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "user@example.com",
    "emails": [
      "user@example.com"
    ],
    "send_test_to": [
      "user@example.com"
    ],
    "contact_id": 0,
    "sample_contact_id": 0
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/campaigns/{id}/send_test', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "email": "user@example.com",
      "emails": [
        "user@example.com"
      ],
      "send_test_to": [
        "user@example.com"
      ],
      "contact_id": 0,
      "sample_contact_id": 0
    }),
});

const data = await response.json();
import requests

payload = {
  "email": "user@example.com",
  "emails": [
    "user@example.com"
  ],
  "send_test_to": [
    "user@example.com"
  ],
  "contact_id": 0,
  "sample_contact_id": 0
}

response = requests.post('https://api.nitrosend.com/v1/my/campaigns/{id}/send_test', json=payload)
data = response.json()
Request Body
{
  "email": "user@example.com",
  "emails": [
    "user@example.com"
  ],
  "send_test_to": [
    "user@example.com"
  ],
  "contact_id": 0,
  "sample_contact_id": 0
}
{
  "sent": 0,
  "results": [
    {
      "email": "string",
      "success": true,
      "status": "delivered",
      "code": "string",
      "error": "string",
      "message_id": 0
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Send a campaign

POST
https://api.nitrosend.com/v1/my/campaigns/{id}/send

Delivers the exact persisted campaign snapshot. Save content, audience, and other authoring changes through the campaign update endpoint first. This endpoint rejects authoring fields rather than merging them during delivery. Pass deliver_at (RFC 3339) to schedule; omit it to send now. Both expected_campaign_updated_at and template_if_version are required so a stale caller cannot send a newer draft accidentally. Returns 422 campaign_locked if the campaign is not editable (live, paused, completed, cancelled, archived, or scheduled within 5 minutes of send). Returns 409 duplicate_campaign_schedule or duplicate_campaign_send when a repeat attempt would create another schedule or overlap an active send; poll /delivery, cancel, or edit the existing scheduled campaign instead.

Body

application/json
expected_campaign_updated_atstring<date-time>required

Exact campaign.updated_at value from the persisted draft being approved for delivery.

template_if_versionintegerrequired

Exact persisted campaign template version being approved for delivery.

deliver_atstring<date-time>

Future delivery time. Omit for immediate delivery.

confirm_send_to_allboolean

Required when the persisted audience is all_contacts.

Parameters

idintegerrequiredpath

Response

200OKCampaign

Campaign sent

409ConflictError

Template version conflict or duplicate send attempt

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Send a campaign
curl -X POST 'https://api.nitrosend.com/v1/my/campaigns/{id}/send' \
  -H 'Content-Type: application/json' \
  -d '{
    "expected_campaign_updated_at": "2024-01-15T09:30:00Z",
    "template_if_version": 0,
    "deliver_at": "2024-01-15T09:30:00Z",
    "confirm_send_to_all": true
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/campaigns/{id}/send', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "expected_campaign_updated_at": "2024-01-15T09:30:00Z",
      "template_if_version": 0,
      "deliver_at": "2024-01-15T09:30:00Z",
      "confirm_send_to_all": true
    }),
});

const data = await response.json();
import requests

payload = {
  "expected_campaign_updated_at": "2024-01-15T09:30:00Z",
  "template_if_version": 0,
  "deliver_at": "2024-01-15T09:30:00Z",
  "confirm_send_to_all": True
}

response = requests.post('https://api.nitrosend.com/v1/my/campaigns/{id}/send', json=payload)
data = response.json()
Request Body
{
  "expected_campaign_updated_at": "2024-01-15T09:30:00Z",
  "template_if_version": 0,
  "deliver_at": "2024-01-15T09:30:00Z",
  "confirm_send_to_all": true
}
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "status": "draft",
  "approval_state": "string",
  "draft_revision_id": 0,
  "draft_revision_digest": "string",
  "draft_approval_state": "pending_review",
  "active_revision_id": 0,
  "active_revision_digest": "string",
  "has_unpublished_changes": true,
  "channel": "email",
  "name": "string",
  "data": {},
  "scheduled_at": "2024-01-15T09:30:00Z",
  "sent_count": 0,
  "dashboard_url": "https://example.com",
  "preview_url": "https://example.com",
  "recipient_snapshot": {
    "requested_recipients": 0,
    "dispatched_recipients": 0,
    "blocked_recipients": 0,
    "requested_send_units": 0,
    "dispatched_send_units": 0,
    "units_per_recipient": 0,
    "send_token": "string",
    "started_at": "2024-01-15T09:30:00Z",
    "completed_at": "2024-01-15T09:30:00Z"
  },
  "last_send_recipients": 0,
  "delivery": {
    "capacity_recovery": {
      "state": "approaching",
      "reason_code": "sending_capacity_warning",
      "blocking_control": "commercial_capacity",
      "usage_percent": 0,
      "requested_quantity": 0,
      "label": "string",
      "detail": "string",
      "capacity": {
        "source": "plan",
        "window_seconds": 86400,
        "status": "known",
        "limit": 0,
        "reserved": 0,
        "accepted": 0,
        "provider_unknown": 0,
        "remaining": 0
      },
      "upgrade_url": "https://example.com",
      "retry_at": "2024-01-15T09:30:00Z",
      "recovery_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      },
      "recovery_actions": [
        {
          "type": "upgrade_plan",
          "label": "string",
          "detail": "string",
          "url": "https://example.com",
          "required_role": "account_owner_or_admin"
        }
      ],
      "owner_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    },
    "campaign_send_token": "string",
    "status": "sending",
    "recipients": 0,
    "sent": 0,
    "failed": 0,
    "pending": 0
  },
  "engagement": {
    "sent": 0,
    "opens": 0,
    "total_opens": 0,
    "open_rate": 0,
    "account": {
      "sent": 0,
      "opens": 0,
      "total_opens": 0,
      "open_rate": 0
    }
  },
  "revenue": {
    "attribution_label": "Attributed revenue. Last click, 7-day window.",
    "currency": "string",
    "mixed_currency": true,
    "attributed_revenue_cents": 0,
    "delivered": 0,
    "attributed_orders": 0,
    "revenue_per_recipient": 0,
    "conversion_rate": 0,
    "attributed_aov": 0,
    "message_breakdown": [
      {
        "message_id": 0,
        "subject": "string",
        "sent_at": "2024-01-15T09:30:00Z",
        "currency": "string",
        "mixed_currency": true,
        "delivered": 0,
        "attributed_orders": 0,
        "attributed_revenue_cents": 0,
        "revenue_per_recipient": 0,
        "conversion_rate": 0,
        "attributed_aov": 0
      }
    ]
  },
  "editable": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "trigger": {
    "id": 0,
    "flow_id": 0,
    "event": "string",
    "audience_type": "lists",
    "segment_id": 0,
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "exclude_segment_ids": [
      0
    ],
    "exclude_contact_list_ids": [
      0
    ],
    "data": {},
    "triggered_count": 0,
    "last_triggered_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "template": {
    "id": 0,
    "name": "string",
    "flow_id": 0,
    "action_id": 0,
    "version": 0,
    "subject": "string",
    "body": "string",
    "preheader": "string",
    "from_name": "string",
    "from_email": "string",
    "reply_to": "string",
    "design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    },
    "variables": {},
    "generation_provenance": {
      "state": "candidate",
      "event_id": 0,
      "candidate_locator": "string",
      "generated_slice_digest": "string",
      "acceptance_id": 0,
      "saved_authored_digest": "string",
      "edit_relation": "identical"
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "templates": [
    {
      "id": 0,
      "name": "string",
      "flow_id": 0,
      "action_id": 0,
      "version": 0,
      "subject": "string",
      "body": "string",
      "preheader": "string",
      "from_name": "string",
      "from_email": "string",
      "reply_to": "string",
      "design": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      },
      "variables": {},
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      },
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Messages

Transactional email and SMS messages

List messages

GET
https://api.nitrosend.com/v1/my/messages

Returns all messages by default. Use source_type to narrow to campaign, flow, transactional, or test sends.

Parameters

source_typestringallcampaignflowtransactionaltestquery

Filter by source. Omit or use 'all' for everything.

flow_idintegerquery

Filter to messages from a specific flow

campaign_idintegerquery

Filter to messages from a specific campaign

datestring<date>query

Filter to messages created on this date

channelstringemailsmsquery
statusstringqueuedsentfailedquery
pageinteger1query
limitinteger<= 10025query

Response

200OKArray<Message>

Paginated list of messages

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List messages
curl -X GET 'https://api.nitrosend.com/v1/my/messages'
const response = await fetch('https://api.nitrosend.com/v1/my/messages', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/messages')
data = response.json()
200
[
  {
    "id": 0,
    "channel": "email",
    "to": "string",
    "subject": "string",
    "status": "queued",
    "provider_id": "string",
    "flow_id": 0,
    "source_type": "campaign",
    "source_name": "string",
    "status_reason_code": "string",
    "status_reason": "string",
    "status_reason_category": "content_review",
    "failure_code": "string",
    "failure_reason": "string",
    "failure_category": "content_review",
    "sent_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z"
  }
]

Send a transactional message

POST
https://api.nitrosend.com/v1/my/messages

Send a transactional email or SMS to a single recipient immediately. No campaign, no audience, no approval required. Use for receipts, password resets, OTPs, order confirmations, and system notifications. A stable idempotency key is strongly recommended via the Idempotency-Key header or idempotency_key body field, and becomes mandatory on 2026-09-01. Before that cutoff, keyless requests are accepted but deprecated: they skip duplicate protection and the response carries Deprecation and Sunset headers. Reuse a key only for an exact retry.

Body

application/json
channelstringemailsmsrequired
tostringrequired

Recipient email address or E.164 phone number

subjectstring

Email subject line (required for email channel)

bodystring

Message body. Required for SMS. For email this is plain text (HTML in this field is escaped) and serves as the plain-text alternative when html is set. To send HTML, use html or template_id.

htmlstring

Pre-rendered HTML body for email, used verbatim as the HTML part (not escaped). Use this to send your own fully-rendered HTML. Mutually exclusive with template_id (email only).

template_idinteger

Load email design from an existing template (email only)

contact_idinteger

Optional contact to personalize with when rendering a template

fromstring

Verified sender email for this email message. May include a display name, for example "Acme hello@example.com".

from_emailstring

Verified sender email for this email message. Alias of from.

from_namestring

Sender display name for this email message

reply_tostring

Reply-to email address for this email message

headersobject

Provider headers for this email message. Structural and Nitrosend-reserved headers are rejected.

tagsobject

Provider tags for this email message. Nitrosend-reserved tag keys are rejected and system tags are always controlled by Nitrosend.

dataobject

Merge variables

mail_actionMailActionDescription

A Mail Action Protocol 0.2 description. The canonical MailSchema core schema is authoritative; this schema restates its shape.

Show child attributes
@contextstringhttps://mailschema.org/contexts/map-0.2.jsonldrequired
@typestringMailActionrequired
@idstring<uri>required

UUID URN identifying the interaction.

profilestringhttps://mailschema.org/profiles/map/0.2required
typeMailActionTypeReferencerequired
Show child attributes
idstring<uri>required
versionstringrequired
contractDigeststringrequired
describedAtstring<date-time>required
expiresAtstring<date-time>required
serviceMailActionServicerequired
Show child attributes
idstring<uri>required
namestringrequired
authoritystringcredentialpossessionrequired
resourcestring<uri>

The RFC 9728 protected resource identifier. Present exactly with credential authority.

executionobjectrequired
Show child attributes
urlstring<uri>required
resultUrlTemplatestringrequired
resultRetentionSecondsinteger[300, 31536000]required
humanUrlstring<uri>required
recipientstring<email>

The address a possession capability was issued to. Present exactly with possession authority.

targetMailActionTargetrequired
Show child attributes
idstring<uri>required
revisionstringrequired
titlestring
digeststringrequired
detailsobject

Defined by the type contract. Content Review 0.3 names the revision this one supersedes.

operationsArray<MailActionOperation>required
Show child attributes
idstringrequired
namestringrequired
descriptionstringrequired
idempotency_keystring

Stable idempotency key (alternative to header). Strongly recommended; mandatory from 2026-09-01.

Parameters

Idempotency-Keystringheader

Strongly recommended; mandatory from 2026-09-01 unless idempotency_key is supplied in the body. Prevents duplicate sends on retry. The same key with the same payload returns the original message; the same key with a different payload returns 409. Before the cutoff, keyless requests succeed with Deprecation and Sunset response headers.

Response

200OKMessage

Existing message returned for idempotency replay

201CreatedMessage

Message created

400Bad RequestError

Missing required idempotency key (enforced from 2026-09-01). Before the cutoff, keyless requests are accepted with Deprecation and Sunset headers.

409Conflictobject | object

Idempotency conflict or explicit sender selection required; no new message is retained in either case

422Unprocessable EntityError & object

Validation failed

503Service UnavailableError & object | object

Admission evidence or the shared hosted-sender root is temporarily unavailable

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Send a transactional message
curl -X POST 'https://api.nitrosend.com/v1/my/messages' \
  -H 'Content-Type: application/json' \
  -d '{
    "channel": "email",
    "to": "string",
    "subject": "string",
    "body": "string",
    "html": "string",
    "template_id": 0,
    "contact_id": 0,
    "from": "string",
    "from_email": "string",
    "from_name": "string",
    "reply_to": "string",
    "headers": {},
    "tags": {},
    "data": {},
    "mail_action": {
      "@context": "https://mailschema.org/contexts/map-0.2.jsonld",
      "@type": "MailAction",
      "@id": "https://example.com",
      "profile": "https://mailschema.org/profiles/map/0.2",
      "type": {
        "id": "https://example.com",
        "version": "string",
        "contractDigest": "string"
      },
      "describedAt": "2024-01-15T09:30:00Z",
      "expiresAt": "2024-01-15T09:30:00Z",
      "service": {
        "id": "https://example.com",
        "name": "string",
        "authority": "credential",
        "resource": "https://example.com",
        "execution": {
          "url": "https://example.com",
          "resultUrlTemplate": "string",
          "resultRetentionSeconds": 300
        },
        "humanUrl": "https://example.com"
      },
      "recipient": "user@example.com",
      "target": {
        "id": "https://example.com",
        "revision": "string",
        "title": "string",
        "digest": "string"
      },
      "details": {},
      "operations": [
        {
          "id": "string",
          "name": "string",
          "description": "string"
        }
      ]
    },
    "idempotency_key": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/messages', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "channel": "email",
      "to": "string",
      "subject": "string",
      "body": "string",
      "html": "string",
      "template_id": 0,
      "contact_id": 0,
      "from": "string",
      "from_email": "string",
      "from_name": "string",
      "reply_to": "string",
      "headers": {},
      "tags": {},
      "data": {},
      "mail_action": {
        "@context": "https://mailschema.org/contexts/map-0.2.jsonld",
        "@type": "MailAction",
        "@id": "https://example.com",
        "profile": "https://mailschema.org/profiles/map/0.2",
        "type": {
          "id": "https://example.com",
          "version": "string",
          "contractDigest": "string"
        },
        "describedAt": "2024-01-15T09:30:00Z",
        "expiresAt": "2024-01-15T09:30:00Z",
        "service": {
          "id": "https://example.com",
          "name": "string",
          "authority": "credential",
          "resource": "https://example.com",
          "execution": {
            "url": "https://example.com",
            "resultUrlTemplate": "string",
            "resultRetentionSeconds": 300
          },
          "humanUrl": "https://example.com"
        },
        "recipient": "user@example.com",
        "target": {
          "id": "https://example.com",
          "revision": "string",
          "title": "string",
          "digest": "string"
        },
        "details": {},
        "operations": [
          {
            "id": "string",
            "name": "string",
            "description": "string"
          }
        ]
      },
      "idempotency_key": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "channel": "email",
  "to": "string",
  "subject": "string",
  "body": "string",
  "html": "string",
  "template_id": 0,
  "contact_id": 0,
  "from": "string",
  "from_email": "string",
  "from_name": "string",
  "reply_to": "string",
  "headers": {},
  "tags": {},
  "data": {},
  "mail_action": {
    "@context": "https://mailschema.org/contexts/map-0.2.jsonld",
    "@type": "MailAction",
    "@id": "https://example.com",
    "profile": "https://mailschema.org/profiles/map/0.2",
    "type": {
      "id": "https://example.com",
      "version": "string",
      "contractDigest": "string"
    },
    "describedAt": "2024-01-15T09:30:00Z",
    "expiresAt": "2024-01-15T09:30:00Z",
    "service": {
      "id": "https://example.com",
      "name": "string",
      "authority": "credential",
      "resource": "https://example.com",
      "execution": {
        "url": "https://example.com",
        "resultUrlTemplate": "string",
        "resultRetentionSeconds": 300
      },
      "humanUrl": "https://example.com"
    },
    "recipient": "user@example.com",
    "target": {
      "id": "https://example.com",
      "revision": "string",
      "title": "string",
      "digest": "string"
    },
    "details": {},
    "operations": [
      {
        "id": "string",
        "name": "string",
        "description": "string"
      }
    ]
  },
  "idempotency_key": "string"
}

response = requests.post('https://api.nitrosend.com/v1/my/messages', json=payload)
data = response.json()
Request Body
{
  "channel": "email",
  "to": "string",
  "subject": "string",
  "body": "string",
  "html": "string",
  "template_id": 0,
  "contact_id": 0,
  "from": "string",
  "from_email": "string",
  "from_name": "string",
  "reply_to": "string",
  "headers": {},
  "tags": {},
  "data": {},
  "mail_action": {
    "@context": "https://mailschema.org/contexts/map-0.2.jsonld",
    "@type": "MailAction",
    "@id": "https://example.com",
    "profile": "https://mailschema.org/profiles/map/0.2",
    "type": {
      "id": "https://example.com",
      "version": "string",
      "contractDigest": "string"
    },
    "describedAt": "2024-01-15T09:30:00Z",
    "expiresAt": "2024-01-15T09:30:00Z",
    "service": {
      "id": "https://example.com",
      "name": "string",
      "authority": "credential",
      "resource": "https://example.com",
      "execution": {
        "url": "https://example.com",
        "resultUrlTemplate": "string",
        "resultRetentionSeconds": 300
      },
      "humanUrl": "https://example.com"
    },
    "recipient": "user@example.com",
    "target": {
      "id": "https://example.com",
      "revision": "string",
      "title": "string",
      "digest": "string"
    },
    "details": {},
    "operations": [
      {
        "id": "string",
        "name": "string",
        "description": "string"
      }
    ]
  },
  "idempotency_key": "string"
}
{
  "id": 0,
  "channel": "email",
  "to": "string",
  "subject": "string",
  "status": "queued",
  "provider_id": "string",
  "flow_id": 0,
  "source_type": "campaign",
  "source_name": "string",
  "status_reason_code": "string",
  "status_reason": "string",
  "status_reason_category": "content_review",
  "failure_code": "string",
  "failure_reason": "string",
  "failure_category": "content_review",
  "sent_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "id": 0,
  "channel": "email",
  "to": "string",
  "subject": "string",
  "status": "queued",
  "provider_id": "string",
  "flow_id": 0,
  "source_type": "campaign",
  "source_name": "string",
  "status_reason_code": "string",
  "status_reason": "string",
  "status_reason_category": "content_review",
  "failure_code": "string",
  "failure_reason": "string",
  "failure_category": "content_review",
  "sent_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "code": 409,
  "message": "string",
  "error": true,
  "error_code": "idempotency_conflict"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "delivery_evidence_pending",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Get a transactional message

GET
https://api.nitrosend.com/v1/my/messages/{id}

Parameters

idintegerrequiredpath

Response

200OKMessage

Message

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get a transactional message
curl -X GET 'https://api.nitrosend.com/v1/my/messages/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/messages/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/messages/{id}')
data = response.json()
{
  "id": 0,
  "channel": "email",
  "to": "string",
  "subject": "string",
  "status": "queued",
  "provider_id": "string",
  "flow_id": 0,
  "source_type": "campaign",
  "source_name": "string",
  "status_reason_code": "string",
  "status_reason": "string",
  "status_reason_category": "content_review",
  "failure_code": "string",
  "failure_reason": "string",
  "failure_category": "content_review",
  "sent_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Render a transactional message's HTML for preview

GET
https://api.nitrosend.com/v1/my/messages/{id}/preview

Returns the as-composed HTML for a message — from its template (rendered design), raw html, or the escaped plain-text body — using the same renderer as the send path, for display in a sandboxed iframe. Non-email or unrenderable messages (deleted/design-less template) return a typed empty state (empty: true) rather than an error.

Parameters

idintegerrequiredpath

Response

200OKobject

Rendered preview, or a typed empty state.

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Render a transactional message's HTML for preview
curl -X GET 'https://api.nitrosend.com/v1/my/messages/{id}/preview'
const response = await fetch('https://api.nitrosend.com/v1/my/messages/{id}/preview', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/messages/{id}/preview')
data = response.json()
{
  "html": "string",
  "format": "template",
  "empty": true,
  "reason": "not_previewable"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Suppressions

Account suppression list and deliverability diagnostics

List suppressions

GET
https://api.nitrosend.com/v1/my/suppressions

Returns the authenticated account's current suppression records by default, including bounded provider diagnostics when the source feedback event is available.

Parameters

idintegerquery

Filter to a specific suppression ID

emailstring<email>query

Filter to a specific suppressed email address

reasonstringhard_bouncesoft_bouncecomplaintmanualadminquery
source_providerstringquery

Filter by provider that emitted the source event

activebooleantruequery

Defaults to true. Set false to list expired suppressions.

pageinteger1query
limitinteger<= 10025query

Response

200OKArray<Suppression>

Paginated list of suppressions

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List suppressions
curl -X GET 'https://api.nitrosend.com/v1/my/suppressions'
const response = await fetch('https://api.nitrosend.com/v1/my/suppressions', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/suppressions')
data = response.json()
200
[
  {
    "id": 0,
    "email": "user@example.com",
    "reason": "hard_bounce",
    "scope": "account_scoped",
    "active": true,
    "contact_id": 0,
    "source_provider": "string",
    "source_event_id": "string",
    "provider_diagnostic": "string",
    "bounce_type": "hard",
    "bounce_subtype": "string",
    "complaint_feedback_type": "string",
    "event_occurred_at": "2024-01-15T09:30:00Z",
    "expires_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]

Webhooks

Signed delivery-event webhooks for transactional email

List webhooks

GET
https://api.nitrosend.com/v1/my/webhooks

The current brand's webhook endpoints, oldest first, each with its newest delivery. Secrets are masked.

Parameters

pageinteger1query
limitinteger<= 10025query

Response

200OKArray<Webhook>

Paginated list of webhooks

401UnauthorizedError

Not authenticated

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List webhooks
curl -X GET 'https://api.nitrosend.com/v1/my/webhooks'
const response = await fetch('https://api.nitrosend.com/v1/my/webhooks', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/webhooks')
data = response.json()
[
  {
    "id": 0,
    "url": "https://example.com",
    "events": [
      "email.sent"
    ],
    "enabled": true,
    "status": "active",
    "failing_since": "2024-01-15T09:30:00Z",
    "secret": "string",
    "last_delivery": {
      "id": 0,
      "event_type": "email.sent",
      "status": "pending",
      "attempts": 0,
      "last_response_status": 0,
      "updated_at": "2024-01-15T09:30:00Z"
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Register a webhook endpoint

POST
https://api.nitrosend.com/v1/my/webhooks

Registers an HTTPS endpoint to receive the chosen events for the brand's transactional email. The response carries the signing secret in full; later reads mask it unless reveal=true. A brand can have at most 10 webhooks. The URL must resolve only to public addresses.

Body

application/json
urlstring<uri>

HTTPS URL that resolves only to public addresses, without credentials.

eventsArray<WebhookEventType>email.sentemail.deliveredemail.bouncedemail.complainedemail.openedemail.clickedemail.failedemail.received
enabledboolean
any

Response

201CreatedWebhook

Webhook created, secret revealed

401UnauthorizedError

Not authenticated

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Register a webhook endpoint
curl -X POST 'https://api.nitrosend.com/v1/my/webhooks' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://example.com",
    "events": [
      "email.sent"
    ],
    "enabled": true
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/webhooks', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "url": "https://example.com",
      "events": [
        "email.sent"
      ],
      "enabled": true
    }),
});

const data = await response.json();
import requests

payload = {
  "url": "https://example.com",
  "events": [
    "email.sent"
  ],
  "enabled": True
}

response = requests.post('https://api.nitrosend.com/v1/my/webhooks', json=payload)
data = response.json()
Request Body
{
  "url": "https://example.com",
  "events": [
    "email.sent"
  ],
  "enabled": true
}
{
  "id": 0,
  "url": "https://example.com",
  "events": [
    "email.sent"
  ],
  "enabled": true,
  "status": "active",
  "failing_since": "2024-01-15T09:30:00Z",
  "secret": "string",
  "last_delivery": {
    "id": 0,
    "event_type": "email.sent",
    "status": "pending",
    "attempts": 0,
    "last_response_status": 0,
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get a webhook

GET
https://api.nitrosend.com/v1/my/webhooks/{id}

Parameters

idintegerrequiredpath
revealbooleanfalsequery

Return the signing secret in full.

Response

200OKWebhook

Webhook

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get a webhook
curl -X GET 'https://api.nitrosend.com/v1/my/webhooks/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/webhooks/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/webhooks/{id}')
data = response.json()
{
  "id": 0,
  "url": "https://example.com",
  "events": [
    "email.sent"
  ],
  "enabled": true,
  "status": "active",
  "failing_since": "2024-01-15T09:30:00Z",
  "secret": "string",
  "last_delivery": {
    "id": 0,
    "event_type": "email.sent",
    "status": "pending",
    "attempts": 0,
    "last_response_status": 0,
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Delete a webhook and its delivery history

DELETE
https://api.nitrosend.com/v1/my/webhooks/{id}

Parameters

idintegerrequiredpath

Response

200OKWebhook

Webhook deleted

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Delete a webhook and its delivery history
curl -X DELETE 'https://api.nitrosend.com/v1/my/webhooks/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/webhooks/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/webhooks/{id}')
data = response.json()
{
  "id": 0,
  "url": "https://example.com",
  "events": [
    "email.sent"
  ],
  "enabled": true,
  "status": "active",
  "failing_since": "2024-01-15T09:30:00Z",
  "secret": "string",
  "last_delivery": {
    "id": 0,
    "event_type": "email.sent",
    "status": "pending",
    "attempts": 0,
    "last_response_status": 0,
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Update a webhook

PATCH
https://api.nitrosend.com/v1/my/webhooks/{id}

Changes the URL, the events, or whether the webhook is on. Turning it off fails the deliveries it still owed; turning it on clears its failing state. Events that occur while it is off are not sent.

Body

application/json
urlstring<uri>

HTTPS URL that resolves only to public addresses, without credentials.

eventsArray<WebhookEventType>email.sentemail.deliveredemail.bouncedemail.complainedemail.openedemail.clickedemail.failedemail.received
enabledboolean

Parameters

idintegerrequiredpath

Response

200OKWebhook

Webhook updated

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update a webhook
curl -X PATCH 'https://api.nitrosend.com/v1/my/webhooks/{id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://example.com",
    "events": [
      "email.sent"
    ],
    "enabled": true
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/webhooks/{id}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "url": "https://example.com",
      "events": [
        "email.sent"
      ],
      "enabled": true
    }),
});

const data = await response.json();
import requests

payload = {
  "url": "https://example.com",
  "events": [
    "email.sent"
  ],
  "enabled": True
}

response = requests.patch('https://api.nitrosend.com/v1/my/webhooks/{id}', json=payload)
data = response.json()
Request Body
{
  "url": "https://example.com",
  "events": [
    "email.sent"
  ],
  "enabled": true
}
{
  "id": 0,
  "url": "https://example.com",
  "events": [
    "email.sent"
  ],
  "enabled": true,
  "status": "active",
  "failing_since": "2024-01-15T09:30:00Z",
  "secret": "string",
  "last_delivery": {
    "id": 0,
    "event_type": "email.sent",
    "status": "pending",
    "attempts": 0,
    "last_response_status": 0,
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Send a test event

POST
https://api.nitrosend.com/v1/my/webhooks/{id}/test

Queues a sample event of the chosen type to this webhook through the normal delivery path, signed and retried like a real event. Its data carries test: true and no message id.

Body

application/json
typeWebhookEventTypeemail.sentemail.deliveredemail.bouncedemail.complainedemail.openedemail.clickedemail.failedemail.received

Parameters

idintegerrequiredpath

Response

202AcceptedWebhookDelivery

Test event queued

404Not FoundError

Resource not found

422Unprocessable EntityError

Unknown event type, or the webhook is off

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Send a test event
curl -X POST 'https://api.nitrosend.com/v1/my/webhooks/{id}/test' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "email.sent"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/webhooks/{id}/test', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "type": "email.sent"
    }),
});

const data = await response.json();
import requests

payload = {
  "type": "email.sent"
}

response = requests.post('https://api.nitrosend.com/v1/my/webhooks/{id}/test', json=payload)
data = response.json()
Request Body
{
  "type": "email.sent"
}
{
  "id": 0,
  "event_id": "550e8400-e29b-41d4-a716-446655440000",
  "event_type": "email.sent",
  "status": "pending",
  "attempts": 0,
  "last_response_status": 0,
  "last_error": "string",
  "next_attempt_at": "2024-01-15T09:30:00Z",
  "payload": {
    "type": "email.sent",
    "timestamp": "2024-01-15T09:30:00Z",
    "data": {
      "message_id": 0,
      "to": "string",
      "subject": "string",
      "idempotency_key": "string",
      "tags": {},
      "test": true,
      "sent_at": "2024-01-15T09:30:00Z",
      "bounce": {
        "type": "hard",
        "subtype": "string"
      },
      "complaint": {
        "feedback_type": "string"
      },
      "url": "string",
      "failure": {
        "code": "string",
        "reason": "string",
        "category": "string"
      }
    }
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

List a webhook's deliveries

GET
https://api.nitrosend.com/v1/my/webhooks/{id}/deliveries

The last 7 days of deliveries to this webhook, newest first.

Parameters

idintegerrequiredpath
pageinteger1query
limitinteger<= 10025query

Response

200OKArray<WebhookDelivery>

Paginated list of deliveries

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List a webhook's deliveries
curl -X GET 'https://api.nitrosend.com/v1/my/webhooks/{id}/deliveries'
const response = await fetch('https://api.nitrosend.com/v1/my/webhooks/{id}/deliveries', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/webhooks/{id}/deliveries')
data = response.json()
[
  {
    "id": 0,
    "event_id": "550e8400-e29b-41d4-a716-446655440000",
    "event_type": "email.sent",
    "status": "pending",
    "attempts": 0,
    "last_response_status": 0,
    "last_error": "string",
    "next_attempt_at": "2024-01-15T09:30:00Z",
    "payload": {
      "type": "email.sent",
      "timestamp": "2024-01-15T09:30:00Z",
      "data": {
        "message_id": 0,
        "to": "string",
        "subject": "string",
        "idempotency_key": "string",
        "tags": {},
        "test": true,
        "sent_at": "2024-01-15T09:30:00Z",
        "bounce": {
          "type": "hard",
          "subtype": "string"
        },
        "complaint": {
          "feedback_type": "string"
        },
        "url": "string",
        "failure": {
          "code": "string",
          "reason": "string",
          "category": "string"
        }
      }
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Templates

Email templates, preview, and component schema

Ingest an image media asset

POST
https://api.nitrosend.com/v1/my/images

REST adapter over the same image ingest capability used by MCP. Send exactly one source: image_data, image_url, multipart file, or a direct-upload signed_id created with purpose image or media_asset. The v1 media contract supports media_kind: image only.

Body

application/json
application/jsonobject
image_datastring

Raw base64 image bytes or a data URL. PNG, JPEG, or WebP only; decoded size must be under 10MB.

image_urlstring<uri>

Public PNG, JPEG, or WebP URL to ingest when Nitro-hosted permanence is desired.

signed_idstring

Active Storage blob signed ID returned by /v1/direct_uploads after uploading bytes with purpose image or media_asset.

filenamestring

Original filename for image_data uploads, or optional filename override for image_url/signed_id sources.

content_typestring | null

Optional MIME type hint when image_data is raw base64 rather than a data URL.

multipart/form-dataobject
filestring<binary>

PNG, JPEG, or WebP file upload. Must be under 10MB.

filenamestring

Optional filename override.

content_typestring | null

Optional MIME type override.

Response

201CreatedImageAsset

Ingested image asset

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Ingest an image media asset
curl -X POST 'https://api.nitrosend.com/v1/my/images' \
  -H 'Content-Type: application/json' \
  -d '{
    "image_data": "string",
    "image_url": "https://example.com",
    "signed_id": "string",
    "filename": "string",
    "content_type": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/images', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "image_data": "string",
      "image_url": "https://example.com",
      "signed_id": "string",
      "filename": "string",
      "content_type": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "image_data": "string",
  "image_url": "https://example.com",
  "signed_id": "string",
  "filename": "string",
  "content_type": "string"
}

response = requests.post('https://api.nitrosend.com/v1/my/images', json=payload)
data = response.json()
Request Body
{
  "image_data": "string",
  "image_url": "https://example.com",
  "signed_id": "string",
  "filename": "string",
  "content_type": "string"
}
{
  "file": "<binary>",
  "filename": "string",
  "content_type": "string"
}
{
  "media_kind": "image",
  "media_url": "https://example.com",
  "image_url": "https://example.com",
  "signed_id": "string",
  "filename": "string",
  "content_type": "string",
  "byte_size": 0,
  "width": 0,
  "height": 0
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

List all templates (paginated)

GET
https://api.nitrosend.com/v1/my/templates

Returns a summary view with section counts (not full design).

Parameters

pageinteger1query
perinteger<= 100100query
scopestringallstandaloneallquery

Use standalone for reusable library templates. Omit or use all to retain the complete designed-template result.

include_previewsbooleanquery

When set, each summary includes rendered preview_html (cached per template version)

Response

200OKArray<TemplateSummary>

Template summaries

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List all templates (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/templates'
const response = await fetch('https://api.nitrosend.com/v1/my/templates', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/templates')
data = response.json()
200
[
  {
    "id": 0,
    "name": "string",
    "version": 0,
    "preview_html": "string",
    "subject": "string",
    "preheader": "string",
    "flow_id": 0,
    "section_count": 0,
    "section_types": [
      "string"
    ],
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]

Create a standalone template

POST
https://api.nitrosend.com/v1/my/templates

Creates one standalone template. Idempotency-Key is required; an exact retry returns the original template, while reuse with changed input returns 409.

Body

application/json
namestring
subjectstring
preheaderstring
generation_provenanceGenerationProvenance

Candidate-bound generation evidence. Save endpoints accept only state: candidate values returned by the generation endpoint. Resource responses may return state: accepted as read-only history.

Show child attributes
statestringcandidateacceptedrequired
event_idintegerrequired
candidate_locatorstring
generated_slice_digeststring
acceptance_idinteger
saved_authored_digeststring
edit_relationstringidenticaledited
if_versioninteger

Required optimistic concurrency token. Use the current template.version.

designEmailDesign

Email template design document

Show child attributes
versioninteger>= 1
sectionsArray<EmailSection>
Show child attributes
typestringheaderherotextimagebuttoncolumnsproductproductsgallerysocialdividerspacerfooterrequired
propsobject

Section-specific properties (see email component spec)

stylesobject
Show child attributes
background_colorstring
section_background_colorstring
paddingstring
alignstringleftcenterright
scalestringdisplayposter
font_sizeinteger
text_colorstring
shapestringsquareroundedarchcircle
remove_gapboolean
border_radiusinteger
themeobject

Theme overrides merged on top of brand theme

Show child attributes
brand_colorstring
bg_colorstring
text_colorstring
font_bodystring
font_headingstring
heading_sizeinteger
body_sizeinteger
radiusinteger
spacing_densitystringcompactnormalspacious
button_background_colorstring
button_text_colorstring
button_paddingstring
logo_urlstring
company_namestring
physical_addressstring
social_linksArray<object>
Show child attributes
platformstring
urlstring

Parameters

Idempotency-Keystringrequiredheader

Response

200OKTemplate

Exact idempotent replay of an existing template

201CreatedTemplate

Created template

400Bad RequestError

Bad request

409ConflictError

Idempotency-Key reused with changed input

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create a standalone template
curl -X POST 'https://api.nitrosend.com/v1/my/templates' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string",
    "subject": "string",
    "preheader": "string",
    "generation_provenance": {
      "state": "candidate",
      "event_id": 0,
      "candidate_locator": "string",
      "generated_slice_digest": "string",
      "acceptance_id": 0,
      "saved_authored_digest": "string",
      "edit_relation": "identical"
    },
    "if_version": 0,
    "design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/templates', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string",
      "subject": "string",
      "preheader": "string",
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      },
      "if_version": 0,
      "design": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string",
  "subject": "string",
  "preheader": "string",
  "generation_provenance": {
    "state": "candidate",
    "event_id": 0,
    "candidate_locator": "string",
    "generated_slice_digest": "string",
    "acceptance_id": 0,
    "saved_authored_digest": "string",
    "edit_relation": "identical"
  },
  "if_version": 0,
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": True,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/templates', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "subject": "string",
  "preheader": "string",
  "generation_provenance": {
    "state": "candidate",
    "event_id": 0,
    "candidate_locator": "string",
    "generated_slice_digest": "string",
    "acceptance_id": 0,
    "saved_authored_digest": "string",
    "edit_relation": "identical"
  },
  "if_version": 0,
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  }
}
{
  "id": 0,
  "name": "string",
  "flow_id": 0,
  "action_id": 0,
  "version": 0,
  "subject": "string",
  "body": "string",
  "preheader": "string",
  "from_name": "string",
  "from_email": "string",
  "reply_to": "string",
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  },
  "variables": {},
  "generation_provenance": {
    "state": "candidate",
    "event_id": 0,
    "candidate_locator": "string",
    "generated_slice_digest": "string",
    "acceptance_id": 0,
    "saved_authored_digest": "string",
    "edit_relation": "identical"
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "id": 0,
  "name": "string",
  "flow_id": 0,
  "action_id": 0,
  "version": 0,
  "subject": "string",
  "body": "string",
  "preheader": "string",
  "from_name": "string",
  "from_email": "string",
  "reply_to": "string",
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  },
  "variables": {},
  "generation_provenance": {
    "state": "candidate",
    "event_id": 0,
    "candidate_locator": "string",
    "generated_slice_digest": "string",
    "acceptance_id": 0,
    "saved_authored_digest": "string",
    "edit_relation": "identical"
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get a template with full design

GET
https://api.nitrosend.com/v1/my/templates/{id}

Parameters

idintegerrequiredpath

Response

200OKTemplate

Full template including design

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get a template with full design
curl -X GET 'https://api.nitrosend.com/v1/my/templates/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/templates/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/templates/{id}')
data = response.json()
{
  "id": 0,
  "name": "string",
  "flow_id": 0,
  "action_id": 0,
  "version": 0,
  "subject": "string",
  "body": "string",
  "preheader": "string",
  "from_name": "string",
  "from_email": "string",
  "reply_to": "string",
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  },
  "variables": {},
  "generation_provenance": {
    "state": "candidate",
    "event_id": 0,
    "candidate_locator": "string",
    "generated_slice_digest": "string",
    "acceptance_id": 0,
    "saved_authored_digest": "string",
    "edit_relation": "identical"
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Delete an unused standalone template

DELETE
https://api.nitrosend.com/v1/my/templates/{id}

Parameters

idintegerrequiredpath
if_versionintegerrequiredquery

Required optimistic concurrency token. Use the current template.version.

Response

200OKobject

Template deleted

404Not FoundError

Resource not found

409ConflictError

Template version conflict or deletion blocked by message/flow history

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Delete an unused standalone template
curl -X DELETE 'https://api.nitrosend.com/v1/my/templates/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/templates/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/templates/{id}')
data = response.json()
{
  "deleted": true,
  "template_id": 0
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Update a template

PATCH
https://api.nitrosend.com/v1/my/templates/{id}

Body

application/json
namestring
subjectstring
bodystring
preheaderstring
if_versionintegerrequired

Required optimistic concurrency token. Use the current template.version. A stale value returns 409 with current_version and expected_version.

from_namestring
from_emailstring<email>
reply_tostring<email>
generation_provenanceGenerationProvenance

Candidate-bound generation evidence. Save endpoints accept only state: candidate values returned by the generation endpoint. Resource responses may return state: accepted as read-only history.

Show child attributes
statestringcandidateacceptedrequired
event_idintegerrequired
candidate_locatorstring
generated_slice_digeststring
acceptance_idinteger
saved_authored_digeststring
edit_relationstringidenticaledited
designEmailDesign

Email template design document

Show child attributes
versioninteger>= 1
sectionsArray<EmailSection>
Show child attributes
typestringheaderherotextimagebuttoncolumnsproductproductsgallerysocialdividerspacerfooterrequired
propsobject

Section-specific properties (see email component spec)

stylesobject
Show child attributes
background_colorstring
section_background_colorstring
paddingstring
alignstringleftcenterright
scalestringdisplayposter
font_sizeinteger
text_colorstring
shapestringsquareroundedarchcircle
remove_gapboolean
border_radiusinteger
themeobject

Theme overrides merged on top of brand theme

Show child attributes
brand_colorstring
bg_colorstring
text_colorstring
font_bodystring
font_headingstring
heading_sizeinteger
body_sizeinteger
radiusinteger
spacing_densitystringcompactnormalspacious
button_background_colorstring
button_text_colorstring
button_paddingstring
logo_urlstring
company_namestring
physical_addressstring
social_linksArray<object>
Show child attributes
platformstring
urlstring

Parameters

idintegerrequiredpath

Response

200OKTemplate

Updated template

409ConflictError

Template version conflict

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update a template
curl -X PATCH 'https://api.nitrosend.com/v1/my/templates/{id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string",
    "subject": "string",
    "body": "string",
    "preheader": "string",
    "if_version": 0,
    "from_name": "string",
    "from_email": "user@example.com",
    "reply_to": "user@example.com",
    "generation_provenance": {
      "state": "candidate",
      "event_id": 0,
      "candidate_locator": "string",
      "generated_slice_digest": "string",
      "acceptance_id": 0,
      "saved_authored_digest": "string",
      "edit_relation": "identical"
    },
    "design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/templates/{id}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string",
      "subject": "string",
      "body": "string",
      "preheader": "string",
      "if_version": 0,
      "from_name": "string",
      "from_email": "user@example.com",
      "reply_to": "user@example.com",
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      },
      "design": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string",
  "subject": "string",
  "body": "string",
  "preheader": "string",
  "if_version": 0,
  "from_name": "string",
  "from_email": "user@example.com",
  "reply_to": "user@example.com",
  "generation_provenance": {
    "state": "candidate",
    "event_id": 0,
    "candidate_locator": "string",
    "generated_slice_digest": "string",
    "acceptance_id": 0,
    "saved_authored_digest": "string",
    "edit_relation": "identical"
  },
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": True,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  }
}

response = requests.patch('https://api.nitrosend.com/v1/my/templates/{id}', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "subject": "string",
  "body": "string",
  "preheader": "string",
  "if_version": 0,
  "from_name": "string",
  "from_email": "user@example.com",
  "reply_to": "user@example.com",
  "generation_provenance": {
    "state": "candidate",
    "event_id": 0,
    "candidate_locator": "string",
    "generated_slice_digest": "string",
    "acceptance_id": 0,
    "saved_authored_digest": "string",
    "edit_relation": "identical"
  },
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  }
}
{
  "id": 0,
  "name": "string",
  "flow_id": 0,
  "action_id": 0,
  "version": 0,
  "subject": "string",
  "body": "string",
  "preheader": "string",
  "from_name": "string",
  "from_email": "string",
  "reply_to": "string",
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  },
  "variables": {},
  "generation_provenance": {
    "state": "candidate",
    "event_id": 0,
    "candidate_locator": "string",
    "generated_slice_digest": "string",
    "acceptance_id": 0,
    "saved_authored_digest": "string",
    "edit_relation": "identical"
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Render an existing template to HTML

GET
https://api.nitrosend.com/v1/my/templates/{id}/render

Renders the template through the shared preview renderer.

Parameters

idintegerrequiredpath

Response

200OKobject

Rendered HTML

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Render an existing template to HTML
curl -X GET 'https://api.nitrosend.com/v1/my/templates/{id}/render'
const response = await fetch('https://api.nitrosend.com/v1/my/templates/{id}/render', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/templates/{id}/render')
data = response.json()
{
  "html": "string",
  "accessibility": {
    "valid": true,
    "warnings": [
      {
        "level": "warning",
        "rule": "image_alt_text",
        "message": "string",
        "suggested_fix": "string",
        "count": 0,
        "min_ratio": 0
      }
    ]
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Send a test email

POST
https://api.nitrosend.com/v1/my/templates/{id}/send_test

Send a test email for the given template. Provide email for an explicit recipient, contact_id to use a contact's email (with merge-tag personalization), or sample_contact_id to personalize an explicit test recipient without sending to the contact. contact_id and sample_contact_id are mutually exclusive. Omit all recipient inputs to use the brand's saved test recipients, falling back to the account owner. Test emails go to the account's own people (owner, members, an active managing account's people) and to addresses at the account's verified domains. Up to 10 other addresses per 30 days are allowed; past that, each refused recipient is reported in results with status: failed and the reason in error, and the other recipients still receive the test. Supply one fresh Idempotency-Key for each user-initiated send and reuse that exact key for transport retries.

Body

application/json
emailstring | Array<string>
emailsArray<string>
send_test_toArray<string>
contact_idinteger
sample_contact_idinteger

Contact whose projected data personalizes the test without changing the test recipient.

Parameters

idintegerrequiredpath
Idempotency-Keystringrequiredheader

Response

200OKobject

Test email sent

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Send a test email
curl -X POST 'https://api.nitrosend.com/v1/my/templates/{id}/send_test' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "user@example.com",
    "emails": [
      "user@example.com"
    ],
    "send_test_to": [
      "user@example.com"
    ],
    "contact_id": 0,
    "sample_contact_id": 0
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/templates/{id}/send_test', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "email": "user@example.com",
      "emails": [
        "user@example.com"
      ],
      "send_test_to": [
        "user@example.com"
      ],
      "contact_id": 0,
      "sample_contact_id": 0
    }),
});

const data = await response.json();
import requests

payload = {
  "email": "user@example.com",
  "emails": [
    "user@example.com"
  ],
  "send_test_to": [
    "user@example.com"
  ],
  "contact_id": 0,
  "sample_contact_id": 0
}

response = requests.post('https://api.nitrosend.com/v1/my/templates/{id}/send_test', json=payload)
data = response.json()
Request Body
{
  "email": "user@example.com",
  "emails": [
    "user@example.com"
  ],
  "send_test_to": [
    "user@example.com"
  ],
  "contact_id": 0,
  "sample_contact_id": 0
}
{
  "sent": 0,
  "results": [
    {
      "email": "string",
      "success": true,
      "status": "delivered",
      "code": "string",
      "error": "string",
      "message_id": 0
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Render an email design to HTML

POST
https://api.nitrosend.com/v1/my/templates/preview

Body

application/json
documentEmailDesignrequired

Email template design document

Show child attributes
versioninteger>= 1
sectionsArray<EmailSection>
Show child attributes
typestringheaderherotextimagebuttoncolumnsproductproductsgallerysocialdividerspacerfooterrequired
propsobject

Section-specific properties (see email component spec)

stylesobject
Show child attributes
background_colorstring
section_background_colorstring
paddingstring
alignstringleftcenterright
scalestringdisplayposter
font_sizeinteger
text_colorstring
shapestringsquareroundedarchcircle
remove_gapboolean
border_radiusinteger
themeobject

Theme overrides merged on top of brand theme

Show child attributes
brand_colorstring
bg_colorstring
text_colorstring
font_bodystring
font_headingstring
heading_sizeinteger
body_sizeinteger
radiusinteger
spacing_densitystringcompactnormalspacious
button_background_colorstring
button_text_colorstring
button_paddingstring
logo_urlstring
company_namestring
physical_addressstring
social_linksArray<object>
Show child attributes
platformstring
urlstring

Response

200OKobject

Rendered HTML

400Bad RequestError

Bad request

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Render an email design to HTML
curl -X POST 'https://api.nitrosend.com/v1/my/templates/preview' \
  -H 'Content-Type: application/json' \
  -d '{
    "document": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/templates/preview', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "document": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "document": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": True,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/templates/preview', json=payload)
data = response.json()
Request Body
{
  "document": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  }
}
{
  "html": "string",
  "accessibility": {
    "valid": true,
    "warnings": [
      {
        "level": "warning",
        "rule": "image_alt_text",
        "message": "string",
        "suggested_fix": "string",
        "count": 0,
        "min_ratio": 0
      }
    ]
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Get the email component schema

GET
https://api.nitrosend.com/v1/my/templates/spec

Returns the full schema for email design sections including all component types, their props, required fields, and defaults. Sourced from config/email_components.yml.

Response

200OKEmailComponentSpec

Email component schema

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get the email component schema
curl -X GET 'https://api.nitrosend.com/v1/my/templates/spec'
const response = await fetch('https://api.nitrosend.com/v1/my/templates/spec', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/templates/spec')
data = response.json()
200
{
  "version": 0,
  "design_guidelines": "string",
  "components": [
    {
      "type": "string",
      "description": "string",
      "tips": [
        "string"
      ],
      "props": {}
    }
  ],
  "style_attributes": [
    {
      "key": "string",
      "label": "string",
      "type": "color",
      "theme_fallback": "string",
      "description": "string",
      "min": 0,
      "max": 0,
      "values": [
        "string"
      ],
      "target": {
        "el": "section",
        "attr": "string"
      }
    }
  ],
  "preview_document": {
    "parameter": "string",
    "description": "string",
    "example": {}
  },
  "variables": {},
  "filters": [
    {
      "name": "string",
      "syntax": "string",
      "description": "string"
    }
  ],
  "theme_attributes": [
    {
      "key": "string",
      "label": "string",
      "type": "color",
      "category": "color",
      "slot": "string",
      "surfaces": [
        "string"
      ],
      "min": 0,
      "max": 0,
      "values": [
        "string"
      ],
      "options": [
        {
          "value": "string",
          "label": "string",
          "description": "string"
        }
      ],
      "transform_table": {},
      "column": true,
      "storage": "string",
      "placeholder": "string",
      "value_resolver": "string",
      "server_owned": true,
      "description": "string"
    }
  ]
}

List the system template library

GET
https://api.nitrosend.com/v1/my/templates/library

Returns the curated system template catalog. Each template ships two faces: its original art direction (design/preview_html) and a brand-matched variant with the palette overrides stripped so the account's colors flow in (branded_design/branded_preview_html). Sourced from the canonical catalog in config/email_templates/, ordered by config/email_templates/index.yml.

Response

200OKArray<EmailLibraryTemplate>

Library templates with original and brand-matched variants

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List the system template library
curl -X GET 'https://api.nitrosend.com/v1/my/templates/library'
const response = await fetch('https://api.nitrosend.com/v1/my/templates/library', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/templates/library')
data = response.json()
200
[
  {
    "id": "string",
    "name": "string",
    "category": "string",
    "tags": [
      "string"
    ],
    "description": "string",
    "subject": "string",
    "preheader": "string",
    "design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    },
    "preview_html": "string",
    "branded_design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    },
    "branded_preview_html": "string"
  }
]

AI-generate an email draft

POST
https://api.nitrosend.com/v1/my/templates/generate

Generate, regenerate, or refine a complete template, campaign-email, or selected flow-email draft through the same authoring spine. This never persists or sends. A flow target addresses exactly one existing email action, never the whole flow. Reusing an idempotency key with changed authoring input returns a conflict.

Body

application/json
goalstringrequired

What the email should accomplish

operationstringgenerateregeneraterefinerequired
edit_scopestringcopydesignboth

Defaults to copy for refine and both otherwise.

user_instructionstring
categorystring

Optional category hint (welcome, newsletter, promotion, etc.)

tonestring

Optional tone override (formal, casual, etc.)

current_draftobject | objectrequired

Complete unsaved editor state to generate or refine.

authoring_targetobject | object | objectrequired

Parameters

Idempotency-Keystringrequiredheader

Retry-stable identity for this generation request.

Response

200OKobject

Generated email design

400Bad Requestobject

Invalid authoring request

409Conflictobject

Generation or template version conflict

422Unprocessable EntityError

Validation error

429Too Many RequestsError

Rate limit exceeded

503Service UnavailableError

Generation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

AI-generate an email draft
curl -X POST 'https://api.nitrosend.com/v1/my/templates/generate' \
  -H 'Content-Type: application/json' \
  -d '{
    "goal": "Welcome new subscribers and introduce the brand",
    "operation": "generate",
    "edit_scope": "copy",
    "user_instruction": "string",
    "category": "string",
    "tone": "string",
    "current_draft": {
      "subject": "string",
      "preheader": "string",
      "body": "string",
      "plain_text_mode": "derived",
      "from_name": "string",
      "from_email": "string",
      "reply_to": "string",
      "design": {
        "version": 0,
        "theme": {},
        "sections": [
          {}
        ]
      }
    },
    "authoring_target": {
      "surface": "template",
      "template_id": 1,
      "if_version": 1
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/templates/generate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "goal": "Welcome new subscribers and introduce the brand",
      "operation": "generate",
      "edit_scope": "copy",
      "user_instruction": "string",
      "category": "string",
      "tone": "string",
      "current_draft": {
        "subject": "string",
        "preheader": "string",
        "body": "string",
        "plain_text_mode": "derived",
        "from_name": "string",
        "from_email": "string",
        "reply_to": "string",
        "design": {
          "version": 0,
          "theme": {},
          "sections": [
            {}
          ]
        }
      },
      "authoring_target": {
        "surface": "template",
        "template_id": 1,
        "if_version": 1
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "goal": "Welcome new subscribers and introduce the brand",
  "operation": "generate",
  "edit_scope": "copy",
  "user_instruction": "string",
  "category": "string",
  "tone": "string",
  "current_draft": {
    "subject": "string",
    "preheader": "string",
    "body": "string",
    "plain_text_mode": "derived",
    "from_name": "string",
    "from_email": "string",
    "reply_to": "string",
    "design": {
      "version": 0,
      "theme": {},
      "sections": [
        {}
      ]
    }
  },
  "authoring_target": {
    "surface": "template",
    "template_id": 1,
    "if_version": 1
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/templates/generate', json=payload)
data = response.json()
Request Body
{
  "goal": "Welcome new subscribers and introduce the brand",
  "operation": "generate",
  "edit_scope": "copy",
  "user_instruction": "string",
  "category": "string",
  "tone": "string",
  "current_draft": {
    "subject": "string",
    "preheader": "string",
    "body": "string",
    "plain_text_mode": "derived",
    "from_name": "string",
    "from_email": "string",
    "reply_to": "string",
    "design": {
      "version": 0,
      "theme": {},
      "sections": [
        {}
      ]
    }
  },
  "authoring_target": {
    "surface": "template",
    "template_id": 1,
    "if_version": 1
  }
}
{
  "design": {},
  "subject": "string",
  "preheader": "string",
  "body": "string",
  "plain_text_mode": "derived",
  "category": "string",
  "prompt_version": "string",
  "generation_provenance": {
    "state": "candidate",
    "event_id": 0,
    "candidate_locator": "string",
    "generated_slice_digest": "string",
    "acceptance_id": 0,
    "saved_authored_digest": "string",
    "edit_relation": "identical"
  },
  "knowledge_used": [
    "string"
  ]
}
{
  "code": "idempotency_key_required",
  "error_code": "idempotency_key_required",
  "message": "string",
  "error": true
}
{
  "code": "template_version_conflict",
  "error_code": "template_version_conflict",
  "message": "string",
  "error": true
}
{
  "error": true,
  "code": "ai_limit_reached",
  "message": "Generation limit reached."
}
{
  "error": true,
  "code": "brand_incomplete",
  "message": "Complete brand setup first."
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "error": true,
  "code": "generation_failed",
  "message": "Generation failed. Try again."
}

Flows

Automation flows and step schema

Save an edited guest flow after sign-in

POST
https://api.nitrosend.com/v1/my/flow_demo/claim

Copies an anonymous demo draft and its reviewed Brand Kit into the authenticated account. The guest token is scoped to one 24-hour demo; exact retries return the same flow. The copied flow remains a draft and does not send until separately approved and activated.

Body

application/json
tokenstringrequired
namestring
graphobjectrequired
Show child attributes
triggerobjectrequired
stepsArray<object>required

Parameters

Idempotency-Keystringrequiredheader

Response

201Createdobject

Claimed draft flow and target Brand

409Conflict

The same demo was claimed with different input or by another account

422Unprocessable Entity

Expired demo, invalid graph, or Brand limit reached

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Save an edited guest flow after sign-in
curl -X POST 'https://api.nitrosend.com/v1/my/flow_demo/claim' \
  -H 'Content-Type: application/json' \
  -d '{
    "token": "string",
    "name": "string",
    "graph": {
      "trigger": {},
      "steps": [
        {}
      ]
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/flow_demo/claim', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "token": "string",
      "name": "string",
      "graph": {
        "trigger": {},
        "steps": [
          {}
        ]
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "token": "string",
  "name": "string",
  "graph": {
    "trigger": {},
    "steps": [
      {}
    ]
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/flow_demo/claim', json=payload)
data = response.json()
Request Body
{
  "token": "string",
  "name": "string",
  "graph": {
    "trigger": {},
    "steps": [
      {}
    ]
  }
}
201
{
  "flow_id": 0,
  "brand_sid": "string"
}

List automation flows (paginated)

GET
https://api.nitrosend.com/v1/my/flows

Returns standalone flows only (excludes campaign-attached flows).

Parameters

pageinteger1query
limitinteger<= 10025query

Response

200OKArray<Flow>

Paginated flows

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List automation flows (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/flows'
const response = await fetch('https://api.nitrosend.com/v1/my/flows', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/flows')
data = response.json()
200
[]

Create a flow

POST
https://api.nitrosend.com/v1/my/flows

Creates a draft flow without delivery authority. Idempotency-Key is required; an exact retry returns the original flow, while reuse with changed input returns 409. Approve or activate in a separate request.

Body

application/json
namestringrequired
triggerFlowTriggerInput
Show child attributes
eventstring

Built-in: contact_add, keyword, message, list_add, list_remove, product_view, checkout, cart_add, cart_remove, cart_abandoned, browse_abandoned. Custom: any lowercase alphanumeric with underscores.

audience_typestring | nulllistssegmentall_contacts

Explicit campaign audience target; null means no audience selected.

segment_idinteger | null
contact_list_idinteger | nulldeprecated

Deprecated — use contact_list_ids

contact_list_idsArray<integer>

Contact list IDs to target

exclude_segment_idsArray<integer>

Segment IDs whose matching contacts are excluded from the recipient set; pass [] to clear

dataobject
stepsArray<FlowStepInput>

Parameters

Idempotency-Keystringrequiredheader

Response

200OKFlow

Exact idempotent replay of an existing flow

201CreatedFlow

Flow created

400Bad RequestError

Bad request

409ConflictError

Idempotency-Key reused with changed input

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create a flow
curl -X POST 'https://api.nitrosend.com/v1/my/flows' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string",
    "trigger": {
      "event": "string",
      "audience_type": "lists",
      "segment_id": 0,
      "contact_list_id": 0,
      "contact_list_ids": [
        0
      ],
      "exclude_segment_ids": [
        0
      ],
      "data": {}
    },
    "steps": []
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/flows', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string",
      "trigger": {
        "event": "string",
        "audience_type": "lists",
        "segment_id": 0,
        "contact_list_id": 0,
        "contact_list_ids": [
          0
        ],
        "exclude_segment_ids": [
          0
        ],
        "data": {}
      },
      "steps": []
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string",
  "trigger": {
    "event": "string",
    "audience_type": "lists",
    "segment_id": 0,
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "exclude_segment_ids": [
      0
    ],
    "data": {}
  },
  "steps": []
}

response = requests.post('https://api.nitrosend.com/v1/my/flows', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "trigger": {
    "event": "string",
    "audience_type": "lists",
    "segment_id": 0,
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "exclude_segment_ids": [
      0
    ],
    "data": {}
  },
  "steps": []
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get a flow

GET
https://api.nitrosend.com/v1/my/flows/{id}

Parameters

idintegerrequiredpath

Response

200OKFlow

Flow with full graph

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get a flow
curl -X GET 'https://api.nitrosend.com/v1/my/flows/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/flows/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/flows/{id}')
data = response.json()
404
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Delete a flow

DELETE
https://api.nitrosend.com/v1/my/flows/{id}

Parameters

idintegerrequiredpath

Response

200OKFlow

Deleted flow

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Delete a flow
curl -X DELETE 'https://api.nitrosend.com/v1/my/flows/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/flows/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/flows/{id}')
data = response.json()

Update a flow

PATCH
https://api.nitrosend.com/v1/my/flows/{id}

Authoring (name, trigger, steps, generation_provenance) and delivery control (status, approval_state) are separate requests and must not be mixed. For graph writes, pass expected_draft_revision_id from the latest flow read to reject stale authored changes. Flow approval/rejection and status: live publication from a draft flow derive the current draft when revision_id is omitted. When supplied, revision_id asserts that the named revision is still the current draft; a stale assertion returns 409. On an already-live flow, status: live without revision_id is a status no-op and does not publish pending changes. Restarting a paused flow with contacts already in progress requires resume_mode. A plain restart is refused when the flow has unpublished changes; supply the current draft revision to publish those changes as part of the restart.

Body

application/json
namestring
statusstringdraftlivepausedarchivedcancelled
approval_statestringapprovedrejected
revision_idinteger | null

Optional current-draft assertion for approval_state and status=live publication. Omission derives the current draft for approval_state and for publication from draft status. On an already-live flow, status=live without revision_id is a no-op. Supply the current draft revision to publish pending changes while restarting a paused flow.

resume_modestringnew_contacts_onlycontinue_existing

Required when restarting a paused flow with contacts in progress. new_contacts_only stops their current journeys. continue_existing restarts waits and releases next steps gradually.

expected_draft_revision_idinteger | null

Exact optimistic concurrency token for authored graph changes.

updated_atstring<date-time>

Optimistic concurrency check

triggerFlowTriggerInput
Show child attributes
eventstring

Built-in: contact_add, keyword, message, list_add, list_remove, product_view, checkout, cart_add, cart_remove, cart_abandoned, browse_abandoned. Custom: any lowercase alphanumeric with underscores.

audience_typestring | nulllistssegmentall_contacts

Explicit campaign audience target; null means no audience selected.

segment_idinteger | null
contact_list_idinteger | nulldeprecated

Deprecated — use contact_list_ids

contact_list_idsArray<integer>

Contact list IDs to target

exclude_segment_idsArray<integer>

Segment IDs whose matching contacts are excluded from the recipient set; pass [] to clear

dataobject
stepsArray<FlowStepInput>
generation_provenanceGenerationProvenance

Candidate-bound generation evidence. Save endpoints accept only state: candidate values returned by the generation endpoint. Resource responses may return state: accepted as read-only history.

Show child attributes
statestringcandidateacceptedrequired
event_idintegerrequired
candidate_locatorstring
generated_slice_digeststring
acceptance_idinteger
saved_authored_digeststring
edit_relationstringidenticaledited

Parameters

idintegerrequiredpath

Response

200OKFlow

Updated flow

409ConflictError

Conflict — the authored draft or requested publication revision is stale

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update a flow
curl -X PATCH 'https://api.nitrosend.com/v1/my/flows/{id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string",
    "status": "draft",
    "approval_state": "approved",
    "revision_id": 0,
    "resume_mode": "new_contacts_only",
    "expected_draft_revision_id": 0,
    "updated_at": "2024-01-15T09:30:00Z",
    "trigger": {
      "event": "string",
      "audience_type": "lists",
      "segment_id": 0,
      "contact_list_id": 0,
      "contact_list_ids": [
        0
      ],
      "exclude_segment_ids": [
        0
      ],
      "data": {}
    },
    "steps": [],
    "generation_provenance": {
      "state": "candidate",
      "event_id": 0,
      "candidate_locator": "string",
      "generated_slice_digest": "string",
      "acceptance_id": 0,
      "saved_authored_digest": "string",
      "edit_relation": "identical"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/flows/{id}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string",
      "status": "draft",
      "approval_state": "approved",
      "revision_id": 0,
      "resume_mode": "new_contacts_only",
      "expected_draft_revision_id": 0,
      "updated_at": "2024-01-15T09:30:00Z",
      "trigger": {
        "event": "string",
        "audience_type": "lists",
        "segment_id": 0,
        "contact_list_id": 0,
        "contact_list_ids": [
          0
        ],
        "exclude_segment_ids": [
          0
        ],
        "data": {}
      },
      "steps": [],
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string",
  "status": "draft",
  "approval_state": "approved",
  "revision_id": 0,
  "resume_mode": "new_contacts_only",
  "expected_draft_revision_id": 0,
  "updated_at": "2024-01-15T09:30:00Z",
  "trigger": {
    "event": "string",
    "audience_type": "lists",
    "segment_id": 0,
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "exclude_segment_ids": [
      0
    ],
    "data": {}
  },
  "steps": [],
  "generation_provenance": {
    "state": "candidate",
    "event_id": 0,
    "candidate_locator": "string",
    "generated_slice_digest": "string",
    "acceptance_id": 0,
    "saved_authored_digest": "string",
    "edit_relation": "identical"
  }
}

response = requests.patch('https://api.nitrosend.com/v1/my/flows/{id}', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "status": "draft",
  "approval_state": "approved",
  "revision_id": 0,
  "resume_mode": "new_contacts_only",
  "expected_draft_revision_id": 0,
  "updated_at": "2024-01-15T09:30:00Z",
  "trigger": {
    "event": "string",
    "audience_type": "lists",
    "segment_id": 0,
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "exclude_segment_ids": [
      0
    ],
    "data": {}
  },
  "steps": [],
  "generation_provenance": {
    "state": "candidate",
    "event_id": 0,
    "candidate_locator": "string",
    "generated_slice_digest": "string",
    "acceptance_id": 0,
    "saved_authored_digest": "string",
    "edit_relation": "identical"
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Preview the choices for restarting a paused flow

GET
https://api.nitrosend.com/v1/my/flows/{id}/resume_plan

Parameters

idintegerrequiredpath

Response

200OKFlowResumePlan

Current restart impact and available choices

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Preview the choices for restarting a paused flow
curl -X GET 'https://api.nitrosend.com/v1/my/flows/{id}/resume_plan'
const response = await fetch('https://api.nitrosend.com/v1/my/flows/{id}/resume_plan', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/flows/{id}/resume_plan')
data = response.json()
{
  "flow_id": 0,
  "status": "draft",
  "open_journey_count": 0,
  "contact_count": 0,
  "waiting_journey_count": 0,
  "scheduled_journey_count": 0,
  "has_unpublished_changes": true,
  "draft_approval_state": "pending_review",
  "requires_choice": true,
  "allowed_modes": [
    "new_contacts_only"
  ],
  "recommended_mode": "new_contacts_only",
  "continue_release_interval_seconds": 1
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Get the flow step type schema

GET
https://api.nitrosend.com/v1/my/flows/spec

Returns the schema for flow step types, trigger events, and audience filters. Flow steps and triggers are sourced from config/flows.yml; filters are sourced from the audience filter registry with lifecycle_flows added from the canonical lifecycle catalog.

Response

200OKFlowSpec

Flow specification

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get the flow step type schema
curl -X GET 'https://api.nitrosend.com/v1/my/flows/spec'
const response = await fetch('https://api.nitrosend.com/v1/my/flows/spec', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/flows/spec')
data = response.json()
200
{
  "filters": {},
  "triggers": [
    {
      "title": "string",
      "event": "string"
    }
  ],
  "steps": [
    {
      "type": "string",
      "title": "string",
      "summary": "string",
      "params": {}
    }
  ],
  "lifecycle_flows": [
    {
      "id": "string",
      "key": "string",
      "goal": "string",
      "name": "string",
      "description": "string",
      "priority": 0,
      "trigger": {
        "event": "string"
      },
      "trigger_needs": "string",
      "steps": [
        {
          "type": "string",
          "duration": 0,
          "subject": "string",
          "preheader": "string",
          "body": "string",
          "design": {}
        }
      ]
    }
  ]
}

List flow templates

GET
https://api.nitrosend.com/v1/my/flow_templates

Returns all available flow templates (static, global — not account-scoped). Each entry includes lean card data and preview_sections from the first email step.

Response

200OKArray<FlowTemplate>

List of flow templates

401UnauthorizedError

Not authenticated

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List flow templates
curl -X GET 'https://api.nitrosend.com/v1/my/flow_templates'
const response = await fetch('https://api.nitrosend.com/v1/my/flow_templates', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/flow_templates')
data = response.json()
[
  {
    "id": "string",
    "type_label": "string",
    "description": "string",
    "category": "string",
    "email_count": 0,
    "step_count": 0,
    "preview_sections": [
      {}
    ]
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Get a flow template

GET
https://api.nitrosend.com/v1/my/flow_templates/{id}

Returns a single flow template including the full trigger and steps graph, ready to pass directly to POST /v1/my/flows.

Parameters

idstringrequiredpath

Flow template slug (e.g. welcome_series)

Response

200OKFlowTemplate & object

Flow template with full graph

401UnauthorizedError

Not authenticated

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get a flow template
curl -X GET 'https://api.nitrosend.com/v1/my/flow_templates/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/flow_templates/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/flow_templates/{id}')
data = response.json()
{
  "id": "string",
  "type_label": "string",
  "description": "string",
  "category": "string",
  "email_count": 0,
  "step_count": 0,
  "preview_sections": [
    {}
  ],
  "trigger": {},
  "steps": [
    {}
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Mail Action Protocol

Authenticated MAP Content Review descriptions, execution, and result recovery

Describe Content Review for the current flow revision

GET
https://api.nitrosend.com/v1/my/map/flows/{flow_id}/content-review

Parameters

flow_idintegerrequiredpath

Response

200OKMailActionDescription

The MAP 0.2 Content Review 0.3 description of the current immutable draft revision

401UnauthorizedError

Not authenticated

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Describe Content Review for the current flow revision
curl -X GET 'https://api.nitrosend.com/v1/my/map/flows/{flow_id}/content-review'
const response = await fetch('https://api.nitrosend.com/v1/my/map/flows/{flow_id}/content-review', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/map/flows/{flow_id}/content-review')
data = response.json()
{
  "@context": "https://mailschema.org/contexts/map-0.2.jsonld",
  "@type": "MailAction",
  "@id": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  },
  "describedAt": "2024-01-15T09:30:00Z",
  "expiresAt": "2024-01-15T09:30:00Z",
  "service": {
    "id": "https://example.com",
    "name": "string",
    "authority": "credential",
    "resource": "https://example.com",
    "execution": {
      "url": "https://example.com",
      "resultUrlTemplate": "string",
      "resultRetentionSeconds": 300
    },
    "humanUrl": "https://example.com"
  },
  "recipient": "user@example.com",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "details": {},
  "operations": [
    {
      "id": "string",
      "name": "string",
      "description": "string"
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

List recorded Content Review requests for a flow

GET
https://api.nitrosend.com/v1/my/map/flows/{flow_id}/content-reviews

Parameters

flow_idintegerrequiredpath

Response

200OKArray<object>

Most recent durable review requests and results

401UnauthorizedError

Not authenticated

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List recorded Content Review requests for a flow
curl -X GET 'https://api.nitrosend.com/v1/my/map/flows/{flow_id}/content-reviews'
const response = await fetch('https://api.nitrosend.com/v1/my/map/flows/{flow_id}/content-reviews', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/map/flows/{flow_id}/content-reviews')
data = response.json()
[
  {
    "request_id": "string",
    "revision_id": 0,
    "operation": "request-changes",
    "input": {},
    "result": {
      "kind": "MapResult",
      "profile": "https://mailschema.org/profiles/map/0.2",
      "requestId": "string",
      "interactionId": "string",
      "descriptionDigest": "string",
      "type": {
        "id": "https://example.com",
        "version": "string",
        "contractDigest": "string"
      },
      "operation": "request-changes",
      "state": "accepted",
      "target": {
        "id": "https://example.com",
        "revision": "string",
        "title": "string",
        "digest": "string"
      },
      "recordedAt": "2024-01-15T09:30:00Z",
      "resultUrl": "https://example.com",
      "approvalUrl": "https://example.com",
      "reason": "declined",
      "output": {}
    },
    "recorded_at": "2024-01-15T09:30:00Z"
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Review one immutable flow revision named by a MAP description

GET
https://api.nitrosend.com/v1/my/map/flows/{flow_id}/revisions/{revision_id}/review

Parameters

flow_idintegerrequiredpath
revision_idintegerrequiredpath

Response

200OKMailActionRevisionReview

The exact revision and its current approval state

401UnauthorizedError

Not authenticated

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Review one immutable flow revision named by a MAP description
curl -X GET 'https://api.nitrosend.com/v1/my/map/flows/{flow_id}/revisions/{revision_id}/review'
const response = await fetch('https://api.nitrosend.com/v1/my/map/flows/{flow_id}/revisions/{revision_id}/review', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/map/flows/{flow_id}/revisions/{revision_id}/review')
data = response.json()
{
  "state": "approval-required",
  "flow": {
    "id": 0,
    "name": "string"
  },
  "revision": {
    "id": 0,
    "digest": "string",
    "approval_state": "pending_review",
    "current": true,
    "trigger": {
      "event": "string"
    },
    "steps": [
      {
        "name": "string",
        "type": "string",
        "wait": 0,
        "subject": "string",
        "preheader": "string",
        "from_name": "string",
        "from_email": "string",
        "html": "string"
      }
    ]
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Protected resource metadata for the MAP API

GET
https://api.nitrosend.com/.well-known/oauth-protected-resource/v1/my/map

OAuth 2.0 Protected Resource Metadata (RFC 9728) for the Mail Action Protocol API. resource is the audience every MAP description names. map_services lists the exact execution and result routes a client may configure instead of trusting URLs from an email.

Response

200OKMailActionProtectedResource

Protected resource metadata

Protected resource metadata for the MAP API
curl -X GET 'https://api.nitrosend.com/.well-known/oauth-protected-resource/v1/my/map'
const response = await fetch('https://api.nitrosend.com/.well-known/oauth-protected-resource/v1/my/map', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/.well-known/oauth-protected-resource/v1/my/map')
data = response.json()
200
{
  "resource": "https://example.com",
  "resource_name": "string",
  "bearer_methods_supported": [
    "header"
  ],
  "map_services": [
    {
      "id": "https://example.com",
      "profiles": [
        "https://example.com"
      ],
      "execution_url": "https://example.com",
      "result_url_template": "string"
    }
  ]
}

Execute a MAP Content Review request

POST
https://api.nitrosend.com/v1/my/map/actions

Parses the body as I-JSON, resolves the interaction from its identifier and compares the description digest, then authorizes the caller, checks the current flow revision and durably deduplicates requestId within the account. The credential travels only in the Authorization header. Other methods answer 405. A Content-Type other than application/json, compared case-insensitively, with at most a charset=utf-8 parameter, answers 415.

Body

application/json

A MAP 0.2 Content Review request. Its operation decides its input.

One of
kindstringrequired
profilestringrequired
requestIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

interactionIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

descriptionDigeststringrequired

SHA-256 over the RFC 8785 canonical form of the description exactly as the email carried it.

typeMailActionTypeReferencerequired
Show child attributes
idstring<uri>required
versionstringrequired
contractDigeststringrequired
kindstringrequired
profilestringrequired
requestIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

interactionIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

descriptionDigeststringrequired

SHA-256 over the RFC 8785 canonical form of the description exactly as the email carried it.

typeMailActionTypeReferencerequired
Show child attributes
idstring<uri>required
versionstringrequired
contractDigeststringrequired

Response

200OKMailActionResult

The review feedback or approval was recorded

202AcceptedMailActionResult

The request was recorded and requires human approval

400Bad RequestMailActionProblem | MailActionUncorrelatedProblem

Invalid MAP or Content Review request. Malformed or non-I-JSON bodies, requests that fail the core request definition, unknown interactions and differing description digests have no MAP correlation members; invalid input is correlated and carries errors.

401UnauthorizedMailActionUncorrelatedProblem

MAP request or result lookup without acceptable Nitrosend authentication

403ForbiddenMailActionProblem | MailActionUncorrelatedProblem

The authenticated principal cannot use this interaction or request identifier

409ConflictMailActionProblem

Stale target, idempotency conflict, or an interaction another request already decided

410GoneMailActionProblem

Interaction and retained result expired

415Unsupported Media TypeHttpProblem

The Content-Type is not application/json with at most a charset=utf-8 parameter

422Unprocessable EntityMailActionProblem

Unsupported type or operation

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Execute a MAP Content Review request
curl -X POST 'https://api.nitrosend.com/v1/my/map/actions' \
  -H 'Content-Type: application/json' \
  -d '{
    "kind": "MapRequest",
    "profile": "https://mailschema.org/profiles/map/0.2",
    "requestId": "string",
    "interactionId": "string",
    "descriptionDigest": "string",
    "type": {
      "id": "https://example.com",
      "version": "string",
      "contractDigest": "string"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/map/actions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "kind": "MapRequest",
      "profile": "https://mailschema.org/profiles/map/0.2",
      "requestId": "string",
      "interactionId": "string",
      "descriptionDigest": "string",
      "type": {
        "id": "https://example.com",
        "version": "string",
        "contractDigest": "string"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "kind": "MapRequest",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "descriptionDigest": "string",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/map/actions', json=payload)
data = response.json()
Request Body
{
  "kind": "MapRequest",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "descriptionDigest": "string",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  }
}
{
  "kind": "MapResult",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "descriptionDigest": "string",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  },
  "operation": "request-changes",
  "state": "accepted",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "recordedAt": "2024-01-15T09:30:00Z",
  "resultUrl": "https://example.com",
  "approvalUrl": "https://example.com",
  "reason": "declined",
  "output": {}
}
{
  "kind": "MapResult",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "descriptionDigest": "string",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  },
  "operation": "request-changes",
  "state": "accepted",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "recordedAt": "2024-01-15T09:30:00Z",
  "resultUrl": "https://example.com",
  "approvalUrl": "https://example.com",
  "reason": "declined",
  "output": {}
}
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "code": "invalid-request",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "errors": [
    {
      "detail": "string",
      "pointer": "string"
    }
  ]
}
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string"
}
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "code": "invalid-request",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "errors": [
    {
      "detail": "string",
      "pointer": "string"
    }
  ]
}
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "code": "invalid-request",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "errors": [
    {
      "detail": "string",
      "pointer": "string"
    }
  ]
}
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "code": "invalid-request",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "errors": [
    {
      "detail": "string",
      "pointer": "string"
    }
  ]
}
{
  "type": "about:blank",
  "title": "string",
  "status": 400
}
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "code": "invalid-request",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "errors": [
    {
      "detail": "string",
      "pointer": "string"
    }
  ]
}

Recover the latest authorized MAP result

GET
https://api.nitrosend.com/v1/my/map/results/{request_id}

Returns the latest response recorded for the request, after rechecking access and settling an approval whose deadline has passed: a result, or the correlated problem the request earned.

Parameters

request_idMailActionUuidUrnrequiredpath

Response

200OKMailActionResult

Latest retained result

202AcceptedMailActionResult

Latest retained result, still awaiting human approval

400Bad RequestMailActionProblem

The recorded invalid-request problem, with its input errors

401UnauthorizedMailActionUncorrelatedProblem

MAP request or result lookup without acceptable Nitrosend authentication

403ForbiddenMailActionProblem | MailActionUncorrelatedProblem

Result access refused

404Not FoundMailActionResultNotFoundProblem | HttpProblem

No retained result in the authenticated scope, as a correlated result-not-found problem. A path whose identifier is not a UUID URN names no result resource and gets a plain 404.

409ConflictMailActionProblem

The recorded stale-target or already-decided problem

410GoneMailActionProblem

The recorded expired-interaction problem

422Unprocessable EntityMailActionProblem

The recorded unsupported-type or unsupported-operation problem

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Recover the latest authorized MAP result
curl -X GET 'https://api.nitrosend.com/v1/my/map/results/{request_id}'
const response = await fetch('https://api.nitrosend.com/v1/my/map/results/{request_id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/map/results/{request_id}')
data = response.json()
{
  "kind": "MapResult",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "descriptionDigest": "string",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  },
  "operation": "request-changes",
  "state": "accepted",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "recordedAt": "2024-01-15T09:30:00Z",
  "resultUrl": "https://example.com",
  "approvalUrl": "https://example.com",
  "reason": "declined",
  "output": {}
}
{
  "kind": "MapResult",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "descriptionDigest": "string",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  },
  "operation": "request-changes",
  "state": "accepted",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "recordedAt": "2024-01-15T09:30:00Z",
  "resultUrl": "https://example.com",
  "approvalUrl": "https://example.com",
  "reason": "declined",
  "output": {}
}
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "code": "invalid-request",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "errors": [
    {
      "detail": "string",
      "pointer": "string"
    }
  ]
}
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string"
}
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "code": "invalid-request",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "errors": [
    {
      "detail": "string",
      "pointer": "string"
    }
  ]
}
{
  "type": "https://mailschema.org/problems/result-not-found",
  "title": "string",
  "status": 404,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "code": "result-not-found"
}
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "code": "invalid-request",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "errors": [
    {
      "detail": "string",
      "pointer": "string"
    }
  ]
}
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "code": "invalid-request",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "errors": [
    {
      "detail": "string",
      "pointer": "string"
    }
  ]
}
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "code": "invalid-request",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "errors": [
    {
      "detail": "string",
      "pointer": "string"
    }
  ]
}

Review an exact MAP Content Review approval request

GET
https://api.nitrosend.com/v1/my/map/approvals/{request_id}

Parameters

request_idMailActionUuidUrnrequiredpath

Response

200OKMailActionApproval

The immutable flow revision and current decision state

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Review an exact MAP Content Review approval request
curl -X GET 'https://api.nitrosend.com/v1/my/map/approvals/{request_id}'
const response = await fetch('https://api.nitrosend.com/v1/my/map/approvals/{request_id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/map/approvals/{request_id}')
data = response.json()
{
  "request_id": "string",
  "state": "approval-required",
  "requested_at": "2024-01-15T09:30:00Z",
  "flow": {
    "id": 0,
    "name": "string"
  },
  "revision": {
    "id": 0,
    "digest": "string",
    "approval_state": "pending_review",
    "current": true,
    "trigger": {
      "event": "string"
    },
    "steps": [
      {
        "name": "string",
        "type": "string",
        "wait": 0,
        "subject": "string",
        "preheader": "string",
        "from_name": "string",
        "from_email": "string",
        "html": "string"
      }
    ]
  },
  "result": {
    "kind": "MapResult",
    "profile": "https://mailschema.org/profiles/map/0.2",
    "requestId": "string",
    "interactionId": "string",
    "descriptionDigest": "string",
    "type": {
      "id": "https://example.com",
      "version": "string",
      "contractDigest": "string"
    },
    "operation": "request-changes",
    "state": "accepted",
    "target": {
      "id": "https://example.com",
      "revision": "string",
      "title": "string",
      "digest": "string"
    },
    "recordedAt": "2024-01-15T09:30:00Z",
    "resultUrl": "https://example.com",
    "approvalUrl": "https://example.com",
    "reason": "declined",
    "output": {}
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Approve or decline the exact flow revision in a retained MAP request

POST
https://api.nitrosend.com/v1/my/map/approvals/{request_id}

A decision takes a signed-in person's bearer credential. A browser cookie session is refused with 401, so no cross-site request can decide.

Body

application/json
decisionstringapprovedeclinerequired

Parameters

request_idMailActionUuidUrnrequiredpath

Response

200OKMailActionApproval

The retained MAP result reached its completed or failed terminal state

400Bad RequestError

Bad request

401UnauthorizedError

Not authenticated

403ForbiddenError

The caller cannot decide this request, or the service's content and sending rules refuse the approval (error_code: approval_refused). The retained result stays approval-required and can still be declined.

404Not FoundError

Resource not found

409ConflictError

The request was not proposed for approval, so there is nothing to decide.

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Approve or decline the exact flow revision in a retained MAP request
curl -X POST 'https://api.nitrosend.com/v1/my/map/approvals/{request_id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "decision": "approve"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/map/approvals/{request_id}', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "decision": "approve"
    }),
});

const data = await response.json();
import requests

payload = {
  "decision": "approve"
}

response = requests.post('https://api.nitrosend.com/v1/my/map/approvals/{request_id}', json=payload)
data = response.json()
Request Body
{
  "decision": "approve"
}
{
  "request_id": "string",
  "state": "approval-required",
  "requested_at": "2024-01-15T09:30:00Z",
  "flow": {
    "id": 0,
    "name": "string"
  },
  "revision": {
    "id": 0,
    "digest": "string",
    "approval_state": "pending_review",
    "current": true,
    "trigger": {
      "event": "string"
    },
    "steps": [
      {
        "name": "string",
        "type": "string",
        "wait": 0,
        "subject": "string",
        "preheader": "string",
        "from_name": "string",
        "from_email": "string",
        "html": "string"
      }
    ]
  },
  "result": {
    "kind": "MapResult",
    "profile": "https://mailschema.org/profiles/map/0.2",
    "requestId": "string",
    "interactionId": "string",
    "descriptionDigest": "string",
    "type": {
      "id": "https://example.com",
      "version": "string",
      "contractDigest": "string"
    },
    "operation": "request-changes",
    "state": "accepted",
    "target": {
      "id": "https://example.com",
      "revision": "string",
      "title": "string",
      "digest": "string"
    },
    "recordedAt": "2024-01-15T09:30:00Z",
    "resultUrl": "https://example.com",
    "approvalUrl": "https://example.com",
    "reason": "declined",
    "output": {}
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Events

Contact event tracking

List events (paginated)

GET
https://api.nitrosend.com/v1/my/events

Parameters

pageinteger1query
limitinteger<= 10050query
eventstringquery

Filter by event type

contact_idintegerquery
created_afterstring<date-time>query
created_beforestring<date-time>query
resource_uidstringquery
resource_namestringquery
testbooleanquery

Response

200OKArray<Event>

Paginated events

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List events (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/events'
const response = await fetch('https://api.nitrosend.com/v1/my/events', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/events')
data = response.json()
200
[
  {
    "id": 0,
    "account_id": 0,
    "contact_id": 0,
    "user_id": 0,
    "event": "string",
    "amount": 0,
    "data": {},
    "idempotency_key": "string",
    "resource_uid": "string",
    "resource_name": "string",
    "resource_url": "string",
    "test": true,
    "generated": true,
    "chain_depth": 0,
    "ip": "string",
    "user_agent": "string",
    "browser": "string",
    "os": "string",
    "device_type": "string",
    "referrer": "string",
    "utm_source": "string",
    "utm_medium": "string",
    "utm_term": "string",
    "utm_content": "string",
    "utm_campaign": "string",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]

Track a contact event

POST
https://api.nitrosend.com/v1/my/events

Requires an idempotency key via the Idempotency-Key header or idempotency_key body param. Duplicate events (same account + event type + idempotency key) return the existing event.

Body

application/json
eventstringrequired

Event type name (lowercase, underscores)

contact_idinteger
contact_emailstring<email>

Alternative to contact_id — resolves contact by email

idempotency_keystring

Idempotency key (alternative to header)

amountnumber<double>
resource_uidstring
resource_namestring
resource_urlstring<uri>
testbooleanfalse
dataobject

Custom event payload (max 32KB)

utm_sourcestring
utm_mediumstring
utm_termstring
utm_contentstring
utm_campaignstring

Parameters

Idempotency-Keystringheader

Idempotency key (alternative to body param)

Response

200OKEvent

Duplicate event (idempotent — returns existing)

201CreatedEvent

Event created

400Bad RequestError

Bad request

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Track a contact event
curl -X POST 'https://api.nitrosend.com/v1/my/events' \
  -H 'Content-Type: application/json' \
  -d '{
    "event": "string",
    "contact_id": 0,
    "contact_email": "user@example.com",
    "idempotency_key": "string",
    "amount": 0,
    "resource_uid": "string",
    "resource_name": "string",
    "resource_url": "https://example.com",
    "test": false,
    "data": {},
    "utm_source": "string",
    "utm_medium": "string",
    "utm_term": "string",
    "utm_content": "string",
    "utm_campaign": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/events', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "event": "string",
      "contact_id": 0,
      "contact_email": "user@example.com",
      "idempotency_key": "string",
      "amount": 0,
      "resource_uid": "string",
      "resource_name": "string",
      "resource_url": "https://example.com",
      "test": false,
      "data": {},
      "utm_source": "string",
      "utm_medium": "string",
      "utm_term": "string",
      "utm_content": "string",
      "utm_campaign": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "event": "string",
  "contact_id": 0,
  "contact_email": "user@example.com",
  "idempotency_key": "string",
  "amount": 0,
  "resource_uid": "string",
  "resource_name": "string",
  "resource_url": "https://example.com",
  "test": False,
  "data": {},
  "utm_source": "string",
  "utm_medium": "string",
  "utm_term": "string",
  "utm_content": "string",
  "utm_campaign": "string"
}

response = requests.post('https://api.nitrosend.com/v1/my/events', json=payload)
data = response.json()
Request Body
{
  "event": "string",
  "contact_id": 0,
  "contact_email": "user@example.com",
  "idempotency_key": "string",
  "amount": 0,
  "resource_uid": "string",
  "resource_name": "string",
  "resource_url": "https://example.com",
  "test": false,
  "data": {},
  "utm_source": "string",
  "utm_medium": "string",
  "utm_term": "string",
  "utm_content": "string",
  "utm_campaign": "string"
}
{
  "id": 0,
  "account_id": 0,
  "contact_id": 0,
  "user_id": 0,
  "event": "string",
  "amount": 0,
  "data": {},
  "idempotency_key": "string",
  "resource_uid": "string",
  "resource_name": "string",
  "resource_url": "string",
  "test": true,
  "generated": true,
  "chain_depth": 0,
  "ip": "string",
  "user_agent": "string",
  "browser": "string",
  "os": "string",
  "device_type": "string",
  "referrer": "string",
  "utm_source": "string",
  "utm_medium": "string",
  "utm_term": "string",
  "utm_content": "string",
  "utm_campaign": "string",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "id": 0,
  "account_id": 0,
  "contact_id": 0,
  "user_id": 0,
  "event": "string",
  "amount": 0,
  "data": {},
  "idempotency_key": "string",
  "resource_uid": "string",
  "resource_name": "string",
  "resource_url": "string",
  "test": true,
  "generated": true,
  "chain_depth": 0,
  "ip": "string",
  "user_agent": "string",
  "browser": "string",
  "os": "string",
  "device_type": "string",
  "referrer": "string",
  "utm_source": "string",
  "utm_medium": "string",
  "utm_term": "string",
  "utm_content": "string",
  "utm_campaign": "string",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

List event names for filter autocomplete

GET
https://api.nitrosend.com/v1/my/events/names

Returns known platform event names plus observed event names for the current brand.

Response

200OKobject

Event name suggestions

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List event names for filter autocomplete
curl -X GET 'https://api.nitrosend.com/v1/my/events/names'
const response = await fetch('https://api.nitrosend.com/v1/my/events/names', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/events/names')
data = response.json()
200
{
  "names": [
    "string"
  ]
}

Get an event

GET
https://api.nitrosend.com/v1/my/events/{id}

Parameters

idintegerrequiredpath

Response

200OKEvent

Event

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get an event
curl -X GET 'https://api.nitrosend.com/v1/my/events/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/events/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/events/{id}')
data = response.json()
{
  "id": 0,
  "account_id": 0,
  "contact_id": 0,
  "user_id": 0,
  "event": "string",
  "amount": 0,
  "data": {},
  "idempotency_key": "string",
  "resource_uid": "string",
  "resource_name": "string",
  "resource_url": "string",
  "test": true,
  "generated": true,
  "chain_depth": 0,
  "ip": "string",
  "user_agent": "string",
  "browser": "string",
  "os": "string",
  "device_type": "string",
  "referrer": "string",
  "utm_source": "string",
  "utm_medium": "string",
  "utm_term": "string",
  "utm_content": "string",
  "utm_campaign": "string",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Delete an event

DELETE
https://api.nitrosend.com/v1/my/events/{id}

Parameters

idintegerrequiredpath

Response

200OKEvent

Deleted event

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Delete an event
curl -X DELETE 'https://api.nitrosend.com/v1/my/events/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/events/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/events/{id}')
data = response.json()
200
{
  "id": 0,
  "account_id": 0,
  "contact_id": 0,
  "user_id": 0,
  "event": "string",
  "amount": 0,
  "data": {},
  "idempotency_key": "string",
  "resource_uid": "string",
  "resource_name": "string",
  "resource_url": "string",
  "test": true,
  "generated": true,
  "chain_depth": 0,
  "ip": "string",
  "user_agent": "string",
  "browser": "string",
  "os": "string",
  "device_type": "string",
  "referrer": "string",
  "utm_source": "string",
  "utm_medium": "string",
  "utm_term": "string",
  "utm_content": "string",
  "utm_campaign": "string",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

Domains

Sending domain verification

List sending domains (paginated)

GET
https://api.nitrosend.com/v1/my/domains

Parameters

pageinteger1query
perinteger<= 10030query

Response

200OKArray<Domain>

Paginated domains

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List sending domains (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/domains'
const response = await fetch('https://api.nitrosend.com/v1/my/domains', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/domains')
data = response.json()
200
[
  {
    "id": 0,
    "brand_id": 0,
    "name": "string",
    "provider": "ses",
    "default_from_domain": "string",
    "sender_authorization_reason": "missing_sender_domain",
    "integration_id": 0,
    "status": "pending",
    "dmarc_policy": "none",
    "dmarc_recommended_policy": "none",
    "dmarc_observed_policy": "none",
    "dns_records": {
      "sending_dns_records": [
        {
          "record_type": "string",
          "name": "string",
          "relative_name": "string",
          "value": "string",
          "priority": "string",
          "valid": "string",
          "purpose": "string",
          "required": true,
          "mail_forwarding": {
            "enabled": true,
            "route_type": "legacy_forward_all",
            "destination_type": "legacy_mx",
            "legacy_mx_records": [
              {
                "host": "string",
                "preference": 0
              }
            ],
            "setup_note": "string"
          }
        }
      ],
      "receiving_dns_records": [
        {
          "record_type": "string",
          "name": "string",
          "relative_name": "string",
          "value": "string",
          "priority": "string",
          "valid": "string",
          "purpose": "string",
          "required": true,
          "mail_forwarding": {
            "enabled": true,
            "route_type": "legacy_forward_all",
            "destination_type": "legacy_mx",
            "legacy_mx_records": [
              {
                "host": "string",
                "preference": 0
              }
            ],
            "setup_note": "string"
          }
        }
      ]
    },
    "inbound_setup": {
      "method": "none",
      "status": "not_configured",
      "mx_scope": "apex",
      "inbox": {
        "id": 0,
        "address": "user@example.com",
        "display_name": "string",
        "status": "active"
      },
      "provider_forwarding": {
        "provider": "google_workspace",
        "forwarding_address": "user@example.com",
        "probe_sent_at": "2024-01-15T09:30:00Z",
        "verified_at": "2024-01-15T09:30:00Z"
      },
      "apex_mx": {
        "mode": "standalone",
        "preparation": {
          "state": "queued",
          "message": "string",
          "failure_code": "string"
        },
        "prepared": true,
        "configured": true,
        "approval_required": true,
        "approval_expires_at": "2024-01-15T09:30:00Z",
        "legacy_provider_label": "string",
        "legacy_mx_records": [
          {
            "host": "string",
            "preference": 0
          }
        ],
        "setup_note": "string"
      }
    },
    "dns_health": {},
    "dns_setup_status": "unchecked",
    "verified_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z"
  }
]

Add a sending domain

POST
https://api.nitrosend.com/v1/my/domains

Initiates domain verification. Returns DNS records that must be added at your domain registrar before calling POST /verify.

Body

application/json
domainobjectrequired
Show child attributes
namestringrequired

e.g. send.example.com

Response

201CreatedDomain

Domain registered with DNS records to configure

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Add a sending domain
curl -X POST 'https://api.nitrosend.com/v1/my/domains' \
  -H 'Content-Type: application/json' \
  -d '{
    "domain": {
      "name": "string"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/domains', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "domain": {
        "name": "string"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "domain": {
    "name": "string"
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/domains', json=payload)
data = response.json()
Request Body
{
  "domain": {
    "name": "string"
  }
}
{
  "id": 0,
  "brand_id": 0,
  "name": "string",
  "provider": "ses",
  "default_from_domain": "string",
  "sender_authorization_reason": "missing_sender_domain",
  "integration_id": 0,
  "status": "pending",
  "dmarc_policy": "none",
  "dmarc_recommended_policy": "none",
  "dmarc_observed_policy": "none",
  "dns_records": {
    "sending_dns_records": [
      {
        "record_type": "string",
        "name": "string",
        "relative_name": "string",
        "value": "string",
        "priority": "string",
        "valid": "string",
        "purpose": "string",
        "required": true,
        "mail_forwarding": {
          "enabled": true,
          "route_type": "legacy_forward_all",
          "destination_type": "legacy_mx",
          "legacy_mx_records": [
            {
              "host": "string",
              "preference": 0
            }
          ],
          "setup_note": "string"
        }
      }
    ],
    "receiving_dns_records": [
      {
        "record_type": "string",
        "name": "string",
        "relative_name": "string",
        "value": "string",
        "priority": "string",
        "valid": "string",
        "purpose": "string",
        "required": true,
        "mail_forwarding": {
          "enabled": true,
          "route_type": "legacy_forward_all",
          "destination_type": "legacy_mx",
          "legacy_mx_records": [
            {
              "host": "string",
              "preference": 0
            }
          ],
          "setup_note": "string"
        }
      }
    ]
  },
  "inbound_setup": {
    "method": "none",
    "status": "not_configured",
    "mx_scope": "apex",
    "inbox": {
      "id": 0,
      "address": "user@example.com",
      "display_name": "string",
      "status": "active"
    },
    "provider_forwarding": {
      "provider": "google_workspace",
      "forwarding_address": "user@example.com",
      "probe_sent_at": "2024-01-15T09:30:00Z",
      "verified_at": "2024-01-15T09:30:00Z"
    },
    "apex_mx": {
      "mode": "standalone",
      "preparation": {
        "state": "queued",
        "message": "string",
        "failure_code": "string"
      },
      "prepared": true,
      "configured": true,
      "approval_required": true,
      "approval_expires_at": "2024-01-15T09:30:00Z",
      "legacy_provider_label": "string",
      "legacy_mx_records": [
        {
          "host": "string",
          "preference": 0
        }
      ],
      "setup_note": "string"
    }
  },
  "dns_health": {},
  "dns_setup_status": "unchecked",
  "verified_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get a domain with DNS records and status

GET
https://api.nitrosend.com/v1/my/domains/{id}

Parameters

idintegerrequiredpath

Response

200OKDomain

Domain

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get a domain with DNS records and status
curl -X GET 'https://api.nitrosend.com/v1/my/domains/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/domains/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/domains/{id}')
data = response.json()
{
  "id": 0,
  "brand_id": 0,
  "name": "string",
  "provider": "ses",
  "default_from_domain": "string",
  "sender_authorization_reason": "missing_sender_domain",
  "integration_id": 0,
  "status": "pending",
  "dmarc_policy": "none",
  "dmarc_recommended_policy": "none",
  "dmarc_observed_policy": "none",
  "dns_records": {
    "sending_dns_records": [
      {
        "record_type": "string",
        "name": "string",
        "relative_name": "string",
        "value": "string",
        "priority": "string",
        "valid": "string",
        "purpose": "string",
        "required": true,
        "mail_forwarding": {
          "enabled": true,
          "route_type": "legacy_forward_all",
          "destination_type": "legacy_mx",
          "legacy_mx_records": [
            {
              "host": "string",
              "preference": 0
            }
          ],
          "setup_note": "string"
        }
      }
    ],
    "receiving_dns_records": [
      {
        "record_type": "string",
        "name": "string",
        "relative_name": "string",
        "value": "string",
        "priority": "string",
        "valid": "string",
        "purpose": "string",
        "required": true,
        "mail_forwarding": {
          "enabled": true,
          "route_type": "legacy_forward_all",
          "destination_type": "legacy_mx",
          "legacy_mx_records": [
            {
              "host": "string",
              "preference": 0
            }
          ],
          "setup_note": "string"
        }
      }
    ]
  },
  "inbound_setup": {
    "method": "none",
    "status": "not_configured",
    "mx_scope": "apex",
    "inbox": {
      "id": 0,
      "address": "user@example.com",
      "display_name": "string",
      "status": "active"
    },
    "provider_forwarding": {
      "provider": "google_workspace",
      "forwarding_address": "user@example.com",
      "probe_sent_at": "2024-01-15T09:30:00Z",
      "verified_at": "2024-01-15T09:30:00Z"
    },
    "apex_mx": {
      "mode": "standalone",
      "preparation": {
        "state": "queued",
        "message": "string",
        "failure_code": "string"
      },
      "prepared": true,
      "configured": true,
      "approval_required": true,
      "approval_expires_at": "2024-01-15T09:30:00Z",
      "legacy_provider_label": "string",
      "legacy_mx_records": [
        {
          "host": "string",
          "preference": 0
        }
      ],
      "setup_note": "string"
    }
  },
  "dns_health": {},
  "dns_setup_status": "unchecked",
  "verified_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Remove a sending domain

DELETE
https://api.nitrosend.com/v1/my/domains/{id}

A paired domain first returns 422 with the exact counterpart impact. Repeat with unpair=true only after the user confirms that outcome.

Parameters

idintegerrequiredpath
unpairbooleanfalsequery

Confirm teardown of an identity pair after reviewing the paired-domain 422 response.

Response

204No Content

Domain deleted

422Unprocessable EntityError & object

Domain is paired or still has dependent inboxes

503Service UnavailableError

Upstream service unavailable

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Remove a sending domain
curl -X DELETE 'https://api.nitrosend.com/v1/my/domains/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/domains/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/domains/{id}')
data = response.json()
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "reason": "domain_paired",
  "domain_id": 0,
  "paired_with": "string",
  "counterpart_removed": true
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Verify domain DNS records

POST
https://api.nitrosend.com/v1/my/domains/{id}/verify

Checks if the required DNS records have propagated. If verified, completes the domain_verified onboarding step and enables sending.

Parameters

idintegerrequiredpath

Response

200OKDomain

Domain verification status

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Verify domain DNS records
curl -X POST 'https://api.nitrosend.com/v1/my/domains/{id}/verify'
const response = await fetch('https://api.nitrosend.com/v1/my/domains/{id}/verify', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/domains/{id}/verify')
data = response.json()
200
{
  "id": 0,
  "brand_id": 0,
  "name": "string",
  "provider": "ses",
  "default_from_domain": "string",
  "sender_authorization_reason": "missing_sender_domain",
  "integration_id": 0,
  "status": "pending",
  "dmarc_policy": "none",
  "dmarc_recommended_policy": "none",
  "dmarc_observed_policy": "none",
  "dns_records": {
    "sending_dns_records": [
      {
        "record_type": "string",
        "name": "string",
        "relative_name": "string",
        "value": "string",
        "priority": "string",
        "valid": "string",
        "purpose": "string",
        "required": true,
        "mail_forwarding": {
          "enabled": true,
          "route_type": "legacy_forward_all",
          "destination_type": "legacy_mx",
          "legacy_mx_records": [
            {
              "host": "string",
              "preference": 0
            }
          ],
          "setup_note": "string"
        }
      }
    ],
    "receiving_dns_records": [
      {
        "record_type": "string",
        "name": "string",
        "relative_name": "string",
        "value": "string",
        "priority": "string",
        "valid": "string",
        "purpose": "string",
        "required": true,
        "mail_forwarding": {
          "enabled": true,
          "route_type": "legacy_forward_all",
          "destination_type": "legacy_mx",
          "legacy_mx_records": [
            {
              "host": "string",
              "preference": 0
            }
          ],
          "setup_note": "string"
        }
      }
    ]
  },
  "inbound_setup": {
    "method": "none",
    "status": "not_configured",
    "mx_scope": "apex",
    "inbox": {
      "id": 0,
      "address": "user@example.com",
      "display_name": "string",
      "status": "active"
    },
    "provider_forwarding": {
      "provider": "google_workspace",
      "forwarding_address": "user@example.com",
      "probe_sent_at": "2024-01-15T09:30:00Z",
      "verified_at": "2024-01-15T09:30:00Z"
    },
    "apex_mx": {
      "mode": "standalone",
      "preparation": {
        "state": "queued",
        "message": "string",
        "failure_code": "string"
      },
      "prepared": true,
      "configured": true,
      "approval_required": true,
      "approval_expires_at": "2024-01-15T09:30:00Z",
      "legacy_provider_label": "string",
      "legacy_mx_records": [
        {
          "host": "string",
          "preference": 0
        }
      ],
      "setup_note": "string"
    }
  },
  "dns_health": {},
  "dns_setup_status": "unchecked",
  "verified_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}

Create an Entri bootstrap session for domain DNS setup

POST
https://api.nitrosend.com/v1/my/domains/{id}/entri_session

Returns a short-lived Entri JWT plus the DNS record payload needed to launch the Entri modal for a domain owned by the current brand. An already-verified apex may request the prepared company-inbox MX cutover only with explicit approval and an exact domain-name confirmation.

Body

application/json
apex_mx_overridebooleanfalse

Explicitly include the prepared company-inbox MX cutover in this session.

apex_mx_confirmationstring

Exact apex domain name being approved. Required when apex_mx_override is true.

Parameters

idintegerrequiredpath

Response

200OKEntriSessionResponse

Entri bootstrap payload

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Domain setup or apex mail cutover is not ready

429Too Many RequestsError

Rate limit exceeded

503Service UnavailableError

Upstream service unavailable

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create an Entri bootstrap session for domain DNS setup
curl -X POST 'https://api.nitrosend.com/v1/my/domains/{id}/entri_session' \
  -H 'Content-Type: application/json' \
  -d '{
    "apex_mx_override": false,
    "apex_mx_confirmation": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/domains/{id}/entri_session', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "apex_mx_override": false,
      "apex_mx_confirmation": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "apex_mx_override": False,
  "apex_mx_confirmation": "string"
}

response = requests.post('https://api.nitrosend.com/v1/my/domains/{id}/entri_session', json=payload)
data = response.json()
Request Body
{
  "apex_mx_override": false,
  "apex_mx_confirmation": "string"
}
{
  "domain": {
    "id": 0,
    "brand_id": 0,
    "name": "string",
    "provider": "ses",
    "default_from_domain": "string",
    "sender_authorization_reason": "missing_sender_domain",
    "integration_id": 0,
    "status": "pending",
    "dmarc_policy": "none",
    "dmarc_recommended_policy": "none",
    "dmarc_observed_policy": "none",
    "dns_records": {
      "sending_dns_records": [
        {
          "record_type": "string",
          "name": "string",
          "relative_name": "string",
          "value": "string",
          "priority": "string",
          "valid": "string",
          "purpose": "string",
          "required": true,
          "mail_forwarding": {
            "enabled": true,
            "route_type": "legacy_forward_all",
            "destination_type": "legacy_mx",
            "legacy_mx_records": [
              {
                "host": "string",
                "preference": 0
              }
            ],
            "setup_note": "string"
          }
        }
      ],
      "receiving_dns_records": [
        {
          "record_type": "string",
          "name": "string",
          "relative_name": "string",
          "value": "string",
          "priority": "string",
          "valid": "string",
          "purpose": "string",
          "required": true,
          "mail_forwarding": {
            "enabled": true,
            "route_type": "legacy_forward_all",
            "destination_type": "legacy_mx",
            "legacy_mx_records": [
              {
                "host": "string",
                "preference": 0
              }
            ],
            "setup_note": "string"
          }
        }
      ]
    },
    "inbound_setup": {
      "method": "none",
      "status": "not_configured",
      "mx_scope": "apex",
      "inbox": {
        "id": 0,
        "address": "user@example.com",
        "display_name": "string",
        "status": "active"
      },
      "provider_forwarding": {
        "provider": "google_workspace",
        "forwarding_address": "user@example.com",
        "probe_sent_at": "2024-01-15T09:30:00Z",
        "verified_at": "2024-01-15T09:30:00Z"
      },
      "apex_mx": {
        "mode": "standalone",
        "preparation": {
          "state": "queued",
          "message": "string",
          "failure_code": "string"
        },
        "prepared": true,
        "configured": true,
        "approval_required": true,
        "approval_expires_at": "2024-01-15T09:30:00Z",
        "legacy_provider_label": "string",
        "legacy_mx_records": [
          {
            "host": "string",
            "preference": 0
          }
        ],
        "setup_note": "string"
      }
    },
    "dns_health": {},
    "dns_setup_status": "unchecked",
    "verified_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z"
  },
  "entri": {
    "application_id": "string",
    "token": "string",
    "prefilled_domain": "string",
    "user_id": "string",
    "dns_records": [
      {
        "type": "string",
        "host": "string",
        "value": "string",
        "ttl": 0,
        "priority": 0
      }
    ],
    "manual_dns_records": {
      "sending_dns_records": [
        {
          "record_type": "string",
          "name": "string",
          "relative_name": "string",
          "value": "string",
          "priority": "string",
          "valid": "string",
          "purpose": "string",
          "required": true,
          "mail_forwarding": {
            "enabled": true,
            "route_type": "legacy_forward_all",
            "destination_type": "legacy_mx",
            "legacy_mx_records": [
              {
                "host": "string",
                "preference": 0
              }
            ],
            "setup_note": "string"
          }
        }
      ],
      "receiving_dns_records": [
        {
          "record_type": "string",
          "name": "string",
          "relative_name": "string",
          "value": "string",
          "priority": "string",
          "valid": "string",
          "purpose": "string",
          "required": true,
          "mail_forwarding": {
            "enabled": true,
            "route_type": "legacy_forward_all",
            "destination_type": "legacy_mx",
            "legacy_mx_records": [
              {
                "host": "string",
                "preference": 0
              }
            ],
            "setup_note": "string"
          }
        }
      ]
    }
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "blockers": [
    "string"
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Configure inbound delivery for a verified domain

PUT
https://api.nitrosend.com/v1/my/domains/{id}/inbound_setup

Selects exactly one inbound method for the current brand's verified domain. Provider forwarding keeps Google Workspace or Microsoft 365 as the primary receiver and allocates one opaque Nitrosend forwarding address. MX mode requires the domain to be ready for Nitrosend receiving; apex domains additionally require a verified forward-all route.

Body

application/json
inbound_setupobjectrequired
Show child attributes
methodstringprovider_forwardingmxrequired
providerstringgoogle_workspacemicrosoft_365

Required when method is provider_forwarding.

local_partstring

Required when the domain does not yet have its included inbox.

display_namestring | null
preparebooleanfalse

Prepare apex receiving before opening the existing Entri MX connection. Does not change DNS.

no_existing_mail_servicebooleanfalse

Explicit first-mailbox choice. Rejected when public MX or a saved route identifies an existing mail service.

Parameters

idintegerrequiredpath

Response

200OKDomain

Updated domain and inbound setup state

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Configure inbound delivery for a verified domain
curl -X PUT 'https://api.nitrosend.com/v1/my/domains/{id}/inbound_setup' \
  -H 'Content-Type: application/json' \
  -d '{
    "inbound_setup": {
      "method": "provider_forwarding",
      "provider": "google_workspace",
      "local_part": "string",
      "display_name": "string",
      "prepare": false,
      "no_existing_mail_service": false
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/domains/{id}/inbound_setup', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "inbound_setup": {
        "method": "provider_forwarding",
        "provider": "google_workspace",
        "local_part": "string",
        "display_name": "string",
        "prepare": false,
        "no_existing_mail_service": false
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "inbound_setup": {
    "method": "provider_forwarding",
    "provider": "google_workspace",
    "local_part": "string",
    "display_name": "string",
    "prepare": False,
    "no_existing_mail_service": False
  }
}

response = requests.put('https://api.nitrosend.com/v1/my/domains/{id}/inbound_setup', json=payload)
data = response.json()
Request Body
{
  "inbound_setup": {
    "method": "provider_forwarding",
    "provider": "google_workspace",
    "local_part": "string",
    "display_name": "string",
    "prepare": false,
    "no_existing_mail_service": false
  }
}
{
  "id": 0,
  "brand_id": 0,
  "name": "string",
  "provider": "ses",
  "default_from_domain": "string",
  "sender_authorization_reason": "missing_sender_domain",
  "integration_id": 0,
  "status": "pending",
  "dmarc_policy": "none",
  "dmarc_recommended_policy": "none",
  "dmarc_observed_policy": "none",
  "dns_records": {
    "sending_dns_records": [
      {
        "record_type": "string",
        "name": "string",
        "relative_name": "string",
        "value": "string",
        "priority": "string",
        "valid": "string",
        "purpose": "string",
        "required": true,
        "mail_forwarding": {
          "enabled": true,
          "route_type": "legacy_forward_all",
          "destination_type": "legacy_mx",
          "legacy_mx_records": [
            {
              "host": "string",
              "preference": 0
            }
          ],
          "setup_note": "string"
        }
      }
    ],
    "receiving_dns_records": [
      {
        "record_type": "string",
        "name": "string",
        "relative_name": "string",
        "value": "string",
        "priority": "string",
        "valid": "string",
        "purpose": "string",
        "required": true,
        "mail_forwarding": {
          "enabled": true,
          "route_type": "legacy_forward_all",
          "destination_type": "legacy_mx",
          "legacy_mx_records": [
            {
              "host": "string",
              "preference": 0
            }
          ],
          "setup_note": "string"
        }
      }
    ]
  },
  "inbound_setup": {
    "method": "none",
    "status": "not_configured",
    "mx_scope": "apex",
    "inbox": {
      "id": 0,
      "address": "user@example.com",
      "display_name": "string",
      "status": "active"
    },
    "provider_forwarding": {
      "provider": "google_workspace",
      "forwarding_address": "user@example.com",
      "probe_sent_at": "2024-01-15T09:30:00Z",
      "verified_at": "2024-01-15T09:30:00Z"
    },
    "apex_mx": {
      "mode": "standalone",
      "preparation": {
        "state": "queued",
        "message": "string",
        "failure_code": "string"
      },
      "prepared": true,
      "configured": true,
      "approval_required": true,
      "approval_expires_at": "2024-01-15T09:30:00Z",
      "legacy_provider_label": "string",
      "legacy_mx_records": [
        {
          "host": "string",
          "preference": 0
        }
      ],
      "setup_note": "string"
    }
  },
  "dns_health": {},
  "dns_setup_status": "unchecked",
  "verified_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Verify provider forwarding for a domain inbox

POST
https://api.nitrosend.com/v1/my/domains/{id}/inbound_setup/probe

Sends a challenge to the configured customer-facing inbox address. The provider-forwarded copy must return through its bound opaque Nitrosend address before the setup becomes active.

Parameters

idintegerrequiredpath

Response

200OKDomain

Domain with refreshed forwarding probe state

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Verify provider forwarding for a domain inbox
curl -X POST 'https://api.nitrosend.com/v1/my/domains/{id}/inbound_setup/probe'
const response = await fetch('https://api.nitrosend.com/v1/my/domains/{id}/inbound_setup/probe', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/domains/{id}/inbound_setup/probe')
data = response.json()
{
  "id": 0,
  "brand_id": 0,
  "name": "string",
  "provider": "ses",
  "default_from_domain": "string",
  "sender_authorization_reason": "missing_sender_domain",
  "integration_id": 0,
  "status": "pending",
  "dmarc_policy": "none",
  "dmarc_recommended_policy": "none",
  "dmarc_observed_policy": "none",
  "dns_records": {
    "sending_dns_records": [
      {
        "record_type": "string",
        "name": "string",
        "relative_name": "string",
        "value": "string",
        "priority": "string",
        "valid": "string",
        "purpose": "string",
        "required": true,
        "mail_forwarding": {
          "enabled": true,
          "route_type": "legacy_forward_all",
          "destination_type": "legacy_mx",
          "legacy_mx_records": [
            {
              "host": "string",
              "preference": 0
            }
          ],
          "setup_note": "string"
        }
      }
    ],
    "receiving_dns_records": [
      {
        "record_type": "string",
        "name": "string",
        "relative_name": "string",
        "value": "string",
        "priority": "string",
        "valid": "string",
        "purpose": "string",
        "required": true,
        "mail_forwarding": {
          "enabled": true,
          "route_type": "legacy_forward_all",
          "destination_type": "legacy_mx",
          "legacy_mx_records": [
            {
              "host": "string",
              "preference": 0
            }
          ],
          "setup_note": "string"
        }
      }
    ]
  },
  "inbound_setup": {
    "method": "none",
    "status": "not_configured",
    "mx_scope": "apex",
    "inbox": {
      "id": 0,
      "address": "user@example.com",
      "display_name": "string",
      "status": "active"
    },
    "provider_forwarding": {
      "provider": "google_workspace",
      "forwarding_address": "user@example.com",
      "probe_sent_at": "2024-01-15T09:30:00Z",
      "verified_at": "2024-01-15T09:30:00Z"
    },
    "apex_mx": {
      "mode": "standalone",
      "preparation": {
        "state": "queued",
        "message": "string",
        "failure_code": "string"
      },
      "prepared": true,
      "configured": true,
      "approval_required": true,
      "approval_expires_at": "2024-01-15T09:30:00Z",
      "legacy_provider_label": "string",
      "legacy_mx_records": [
        {
          "host": "string",
          "preference": 0
        }
      ],
      "setup_note": "string"
    }
  },
  "dns_health": {},
  "dns_setup_status": "unchecked",
  "verified_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Integrations

BYO provider integration management

List integrations (paginated)

GET
https://api.nitrosend.com/v1/my/integrations

Parameters

categorystringemailsmscrmquery
pageinteger1query
perinteger<= 10030query

Response

200OKArray<Integration>

Paginated integrations

400Bad RequestError

Bad request

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List integrations (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/integrations'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/integrations')
data = response.json()
[
  {
    "id": 0,
    "provider": "mailgun",
    "category": "email",
    "active": true,
    "primary": true,
    "status": "pending",
    "connected_at": "2024-01-15T09:30:00Z",
    "last_tested_at": "2024-01-15T09:30:00Z",
    "error_message": "string",
    "config_summary": {},
    "secret_hints": {},
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Create or connect an email provider integration

POST
https://api.nitrosend.com/v1/my/integrations

Body

application/json
integrationMailgunIntegrationInput | SesIntegrationInput | PostmarkIntegrationInput | ResendIntegrationInput | SendgridIntegrationInputrequired

Response

201CreatedIntegration

Integration created

400Bad RequestError

Bad request

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create or connect an email provider integration
curl -X POST 'https://api.nitrosend.com/v1/my/integrations' \
  -H 'Content-Type: application/json' \
  -d '{
    "integration": {
      "provider": "mailgun",
      "api_key": "string",
      "domain": "string",
      "region": "string",
      "active": true
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "integration": {
        "provider": "mailgun",
        "api_key": "string",
        "domain": "string",
        "region": "string",
        "active": true
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "integration": {
    "provider": "mailgun",
    "api_key": "string",
    "domain": "string",
    "region": "string",
    "active": True
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/integrations', json=payload)
data = response.json()
Request Body
{
  "integration": {
    "provider": "mailgun",
    "api_key": "string",
    "domain": "string",
    "region": "string",
    "active": true
  }
}
{
  "id": 0,
  "provider": "mailgun",
  "category": "email",
  "active": true,
  "primary": true,
  "status": "pending",
  "connected_at": "2024-01-15T09:30:00Z",
  "last_tested_at": "2024-01-15T09:30:00Z",
  "error_message": "string",
  "config_summary": {},
  "secret_hints": {},
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get an integration

GET
https://api.nitrosend.com/v1/my/integrations/{id}

Parameters

idintegerrequiredpath

Response

200OKIntegration

Integration

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get an integration
curl -X GET 'https://api.nitrosend.com/v1/my/integrations/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/integrations/{id}')
data = response.json()
{
  "id": 0,
  "provider": "mailgun",
  "category": "email",
  "active": true,
  "primary": true,
  "status": "pending",
  "connected_at": "2024-01-15T09:30:00Z",
  "last_tested_at": "2024-01-15T09:30:00Z",
  "error_message": "string",
  "config_summary": {},
  "secret_hints": {},
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Disconnect and delete an integration

DELETE
https://api.nitrosend.com/v1/my/integrations/{id}

Parameters

idintegerrequiredpath
confirmbooleanrequiredquery

Must be true to confirm the destructive action.

Response

204No Content

Integration deleted

400Bad RequestError

Bad request

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Disconnect and delete an integration
curl -X DELETE 'https://api.nitrosend.com/v1/my/integrations/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/integrations/{id}')
data = response.json()
400
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Update an email provider integration

PATCH
https://api.nitrosend.com/v1/my/integrations/{id}

Updates credentials or operational fields for an existing email provider. The provider cannot be changed once the integration exists.

Body

application/json
integrationMailgunIntegrationInput | SesIntegrationInput | PostmarkIntegrationInput | ResendIntegrationInput | SendgridIntegrationInputrequired

Parameters

idintegerrequiredpath

Response

200OKIntegration

Integration updated

400Bad RequestError

Bad request

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update an email provider integration
curl -X PATCH 'https://api.nitrosend.com/v1/my/integrations/{id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "integration": {
      "provider": "mailgun",
      "api_key": "string",
      "domain": "string",
      "region": "string",
      "active": true
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/{id}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "integration": {
        "provider": "mailgun",
        "api_key": "string",
        "domain": "string",
        "region": "string",
        "active": true
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "integration": {
    "provider": "mailgun",
    "api_key": "string",
    "domain": "string",
    "region": "string",
    "active": True
  }
}

response = requests.patch('https://api.nitrosend.com/v1/my/integrations/{id}', json=payload)
data = response.json()
Request Body
{
  "integration": {
    "provider": "mailgun",
    "api_key": "string",
    "domain": "string",
    "region": "string",
    "active": true
  }
}
{
  "id": 0,
  "provider": "mailgun",
  "category": "email",
  "active": true,
  "primary": true,
  "status": "pending",
  "connected_at": "2024-01-15T09:30:00Z",
  "last_tested_at": "2024-01-15T09:30:00Z",
  "error_message": "string",
  "config_summary": {},
  "secret_hints": {},
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Test integration connectivity

POST
https://api.nitrosend.com/v1/my/integrations/{id}/test

Parameters

idintegerrequiredpath

Response

200OKIntegration

Tested integration

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Test integration connectivity
curl -X POST 'https://api.nitrosend.com/v1/my/integrations/{id}/test'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/{id}/test', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/integrations/{id}/test')
data = response.json()
{
  "id": 0,
  "provider": "mailgun",
  "category": "email",
  "active": true,
  "primary": true,
  "status": "pending",
  "connected_at": "2024-01-15T09:30:00Z",
  "last_tested_at": "2024-01-15T09:30:00Z",
  "error_message": "string",
  "config_summary": {},
  "secret_hints": {},
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Set an integration as the primary provider for its category

PATCH
https://api.nitrosend.com/v1/my/integrations/{id}/primary

Parameters

idintegerrequiredpath

Response

200OKIntegration

Integration marked primary

400Bad RequestError

Bad request

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Set an integration as the primary provider for its category
curl -X PATCH 'https://api.nitrosend.com/v1/my/integrations/{id}/primary'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/{id}/primary', {
  method: 'PATCH',
});

const data = await response.json();
import requests

response = requests.patch('https://api.nitrosend.com/v1/my/integrations/{id}/primary')
data = response.json()
{
  "id": 0,
  "provider": "mailgun",
  "category": "email",
  "active": true,
  "primary": true,
  "status": "pending",
  "connected_at": "2024-01-15T09:30:00Z",
  "last_tested_at": "2024-01-15T09:30:00Z",
  "error_message": "string",
  "config_summary": {},
  "secret_hints": {},
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Get an integration's versioned profile sync contract

GET
https://api.nitrosend.com/v1/my/integrations/{integration_id}/sync_configuration

Parameters

integration_idintegerrequiredpath

Response

200OKIntegrationSyncConfiguration

Safe sync configuration

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get an integration's versioned profile sync contract
curl -X GET 'https://api.nitrosend.com/v1/my/integrations/{integration_id}/sync_configuration'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/{integration_id}/sync_configuration', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/integrations/{integration_id}/sync_configuration')
data = response.json()
{
  "integration_id": 0,
  "provider": "string",
  "sync_contract": {
    "version": 1,
    "mirror_lists": true,
    "updated_at": "2024-01-15T09:30:00Z",
    "objects": [
      {
        "object_id": "string",
        "object_slug": "string",
        "label": "string",
        "mode": "addressable",
        "enabled": true,
        "field_policy": "all_supported",
        "selected_fields": [
          "string"
        ],
        "excluded_fields": [
          "string"
        ],
        "relationship": {
          "attribute_slug": "string",
          "target_object_slug": "people"
        },
        "trait_mapping": {
          "kind": "deal_pipeline",
          "stage_attribute": "string",
          "closed_stage_values": [
            "string"
          ],
          "amount_attribute": "string",
          "currency_attribute": "string"
        },
        "managed_audience_mapping_key": "string",
        "mirror_lists": true
      }
    ]
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Validate and update an integration's profile sync contract

PATCH
https://api.nitrosend.com/v1/my/integrations/{integration_id}/sync_configuration

Body

application/json
sync_contractIntegrationSyncContractrequired
Show child attributes
versioninteger1required
mirror_listsbooleanrequired
updated_atstring<date-time> | null
objectsArray<IntegrationSyncObjectSelection>required
Show child attributes
object_idstring
object_slugstringrequired
labelstring
modestringaddressablerelatedrequired
enabledbooleantrue
field_policystringall_supportedselected
selected_fieldsArray<string>
excluded_fieldsArray<string>
relationshipobject
Show child attributes
attribute_slugstring
target_object_slugstringpeopleusers
trait_mappingIntegrationSyncTraitMapping
Show child attributes
kindstringdeal_pipelinerequired
stage_attributestringrequired
closed_stage_valuesArray<string>required
amount_attributestring
currency_attributestring
managed_audience_mapping_keystring
mirror_listsboolean

Parameters

integration_idintegerrequiredpath
confirm_deselectionbooleanfalsequery

Response

200OKIntegrationSyncConfiguration

Updated safe sync configuration

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Validate and update an integration's profile sync contract
curl -X PATCH 'https://api.nitrosend.com/v1/my/integrations/{integration_id}/sync_configuration' \
  -H 'Content-Type: application/json' \
  -d '{
    "sync_contract": {
      "version": 1,
      "mirror_lists": true,
      "updated_at": "2024-01-15T09:30:00Z",
      "objects": [
        {
          "object_id": "string",
          "object_slug": "string",
          "label": "string",
          "mode": "addressable",
          "enabled": true,
          "field_policy": "all_supported",
          "selected_fields": [
            "string"
          ],
          "excluded_fields": [
            "string"
          ],
          "relationship": {
            "attribute_slug": "string",
            "target_object_slug": "people"
          },
          "trait_mapping": {
            "kind": "deal_pipeline",
            "stage_attribute": "string",
            "closed_stage_values": [
              "string"
            ],
            "amount_attribute": "string",
            "currency_attribute": "string"
          },
          "managed_audience_mapping_key": "string",
          "mirror_lists": true
        }
      ]
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/{integration_id}/sync_configuration', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "sync_contract": {
        "version": 1,
        "mirror_lists": true,
        "updated_at": "2024-01-15T09:30:00Z",
        "objects": [
          {
            "object_id": "string",
            "object_slug": "string",
            "label": "string",
            "mode": "addressable",
            "enabled": true,
            "field_policy": "all_supported",
            "selected_fields": [
              "string"
            ],
            "excluded_fields": [
              "string"
            ],
            "relationship": {
              "attribute_slug": "string",
              "target_object_slug": "people"
            },
            "trait_mapping": {
              "kind": "deal_pipeline",
              "stage_attribute": "string",
              "closed_stage_values": [
                "string"
              ],
              "amount_attribute": "string",
              "currency_attribute": "string"
            },
            "managed_audience_mapping_key": "string",
            "mirror_lists": true
          }
        ]
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "sync_contract": {
    "version": 1,
    "mirror_lists": True,
    "updated_at": "2024-01-15T09:30:00Z",
    "objects": [
      {
        "object_id": "string",
        "object_slug": "string",
        "label": "string",
        "mode": "addressable",
        "enabled": True,
        "field_policy": "all_supported",
        "selected_fields": [
          "string"
        ],
        "excluded_fields": [
          "string"
        ],
        "relationship": {
          "attribute_slug": "string",
          "target_object_slug": "people"
        },
        "trait_mapping": {
          "kind": "deal_pipeline",
          "stage_attribute": "string",
          "closed_stage_values": [
            "string"
          ],
          "amount_attribute": "string",
          "currency_attribute": "string"
        },
        "managed_audience_mapping_key": "string",
        "mirror_lists": True
      }
    ]
  }
}

response = requests.patch('https://api.nitrosend.com/v1/my/integrations/{integration_id}/sync_configuration', json=payload)
data = response.json()
Request Body
{
  "sync_contract": {
    "version": 1,
    "mirror_lists": true,
    "updated_at": "2024-01-15T09:30:00Z",
    "objects": [
      {
        "object_id": "string",
        "object_slug": "string",
        "label": "string",
        "mode": "addressable",
        "enabled": true,
        "field_policy": "all_supported",
        "selected_fields": [
          "string"
        ],
        "excluded_fields": [
          "string"
        ],
        "relationship": {
          "attribute_slug": "string",
          "target_object_slug": "people"
        },
        "trait_mapping": {
          "kind": "deal_pipeline",
          "stage_attribute": "string",
          "closed_stage_values": [
            "string"
          ],
          "amount_attribute": "string",
          "currency_attribute": "string"
        },
        "managed_audience_mapping_key": "string",
        "mirror_lists": true
      }
    ]
  }
}
{
  "integration_id": 0,
  "provider": "string",
  "sync_contract": {
    "version": 1,
    "mirror_lists": true,
    "updated_at": "2024-01-15T09:30:00Z",
    "objects": [
      {
        "object_id": "string",
        "object_slug": "string",
        "label": "string",
        "mode": "addressable",
        "enabled": true,
        "field_policy": "all_supported",
        "selected_fields": [
          "string"
        ],
        "excluded_fields": [
          "string"
        ],
        "relationship": {
          "attribute_slug": "string",
          "target_object_slug": "people"
        },
        "trait_mapping": {
          "kind": "deal_pipeline",
          "stage_attribute": "string",
          "closed_stage_values": [
            "string"
          ],
          "amount_attribute": "string",
          "currency_attribute": "string"
        },
        "managed_audience_mapping_key": "string",
        "mirror_lists": true
      }
    ]
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Discover safe provider objects and attributes for profile sync

GET
https://api.nitrosend.com/v1/my/integrations/{integration_id}/sync_configuration/discovery

Parameters

integration_idintegerrequiredpath

Response

200OKIntegrationSyncConfiguration & object

Sync configuration and bounded provider discovery metadata

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Discover safe provider objects and attributes for profile sync
curl -X GET 'https://api.nitrosend.com/v1/my/integrations/{integration_id}/sync_configuration/discovery'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/{integration_id}/sync_configuration/discovery', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/integrations/{integration_id}/sync_configuration/discovery')
data = response.json()
{
  "integration_id": 0,
  "provider": "string",
  "sync_contract": {
    "version": 1,
    "mirror_lists": true,
    "updated_at": "2024-01-15T09:30:00Z",
    "objects": [
      {
        "object_id": "string",
        "object_slug": "string",
        "label": "string",
        "mode": "addressable",
        "enabled": true,
        "field_policy": "all_supported",
        "selected_fields": [
          "string"
        ],
        "excluded_fields": [
          "string"
        ],
        "relationship": {
          "attribute_slug": "string",
          "target_object_slug": "people"
        },
        "trait_mapping": {
          "kind": "deal_pipeline",
          "stage_attribute": "string",
          "closed_stage_values": [
            "string"
          ],
          "amount_attribute": "string",
          "currency_attribute": "string"
        },
        "managed_audience_mapping_key": "string",
        "mirror_lists": true
      }
    ]
  },
  "discovery": {
    "provider": "string",
    "version": 1,
    "truncated": true,
    "objects": [
      {
        "object_id": "string",
        "object_slug": "string",
        "singular_noun": "string",
        "plural_noun": "string",
        "eligible": true,
        "recommended_mode": "addressable",
        "ineligible_reason": "string",
        "attributes_truncated": true,
        "attributes": [
          {
            "attribute_id": "string",
            "attribute_slug": "string",
            "title": "string",
            "type": "string",
            "classification": "canonical_scalar",
            "required": true,
            "unique": true,
            "multiselect": true,
            "target_object_slugs": [
              "string"
            ],
            "options": [
              "string"
            ]
          }
        ],
        "relationship_attributes": [
          {
            "attribute_id": "string",
            "attribute_slug": "string",
            "title": "string",
            "type": "string",
            "classification": "canonical_scalar",
            "required": true,
            "unique": true,
            "multiselect": true,
            "target_object_slugs": [
              "string"
            ],
            "options": [
              "string"
            ]
          }
        ]
      }
    ]
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Start Attio OAuth connect flow

POST
https://api.nitrosend.com/v1/my/integrations/attio/connect

Returns an Attio OAuth authorize URL for the authenticated account/brand. The response URL includes a signed state payload and the API callback URI.

Response

200OKobject

OAuth authorize URL

401UnauthorizedError

Not authenticated

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Start Attio OAuth connect flow
curl -X POST 'https://api.nitrosend.com/v1/my/integrations/attio/connect'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/attio/connect', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/integrations/attio/connect')
data = response.json()
{
  "authorize_url": "https://example.com"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Start HubSpot OAuth connect flow

POST
https://api.nitrosend.com/v1/my/integrations/hubspot/connect

Returns a HubSpot OAuth authorize URL for the authenticated account/brand. The response URL includes a signed state payload and the API callback URI.

Response

200OKobject

OAuth authorize URL

401UnauthorizedError

Not authenticated

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Start HubSpot OAuth connect flow
curl -X POST 'https://api.nitrosend.com/v1/my/integrations/hubspot/connect'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/hubspot/connect', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/integrations/hubspot/connect')
data = response.json()
{
  "authorize_url": "https://example.com"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Start Shopify OAuth connect flow

POST
https://api.nitrosend.com/v1/my/integrations/shopify/connect

Returns a Shopify OAuth authorize URL for the authenticated account/brand. The request accepts a myshopify.com shop domain or shop slug. The response URL includes a signed state payload and the API callback URI.

Body

application/json
shopifyobjectrequired
Show child attributes
shopstringrequired

Response

200OKobject

OAuth authorize URL

401UnauthorizedError

Not authenticated

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Start Shopify OAuth connect flow
curl -X POST 'https://api.nitrosend.com/v1/my/integrations/shopify/connect' \
  -H 'Content-Type: application/json' \
  -d '{
    "shopify": {
      "shop": "test-shop.myshopify.com"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/shopify/connect', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "shopify": {
        "shop": "test-shop.myshopify.com"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "shopify": {
    "shop": "test-shop.myshopify.com"
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/integrations/shopify/connect', json=payload)
data = response.json()
Request Body
{
  "shopify": {
    "shop": "test-shop.myshopify.com"
  }
}
{
  "authorize_url": "https://example.com"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Connect a merchant-owned Shopify app

POST
https://api.nitrosend.com/v1/my/integrations/shopify/credentials

Connects an API-only Shopify app owned by the same Shopify organization as its store. Nitrosend exchanges the client credentials server-side, verifies the authenticated shop and granted Admin API scopes, then stores the access token and client secret encrypted. Repeating the request for the same brand and shop verifies the new credentials before replacing the current connection. The response never includes client credentials or an access token.

Body

application/json
shopifyobjectrequired
Show child attributes
shopstringrequired

Permanent myshopify.com domain or shop slug.

client_idstringrequiredwrite only

Client ID for the merchant-owned Shopify app.

client_secretstring<password>requiredwrite only

Client secret for the merchant-owned Shopify app.

Response

200OKIntegration

Existing merchant-managed Shopify connection replaced

201CreatedIntegration

Merchant-managed Shopify connection created

401UnauthorizedError

Not authenticated

422Unprocessable EntityError & object

Missing fields, invalid credentials, missing scopes, or a shop ownership conflict

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Connect a merchant-owned Shopify app
curl -X POST 'https://api.nitrosend.com/v1/my/integrations/shopify/credentials' \
  -H 'Content-Type: application/json' \
  -d '{
    "shopify": {
      "shop": "string",
      "client_id": "string",
      "client_secret": "********"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/shopify/credentials', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "shopify": {
        "shop": "string",
        "client_id": "string",
        "client_secret": "********"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "shopify": {
    "shop": "string",
    "client_id": "string",
    "client_secret": "********"
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/integrations/shopify/credentials', json=payload)
data = response.json()
Request Body
{
  "shopify": {
    "shop": "string",
    "client_id": "string",
    "client_secret": "********"
  }
}
{
  "id": 0,
  "provider": "mailgun",
  "category": "email",
  "active": true,
  "primary": true,
  "status": "pending",
  "connected_at": "2024-01-15T09:30:00Z",
  "last_tested_at": "2024-01-15T09:30:00Z",
  "error_message": "string",
  "config_summary": {},
  "secret_hints": {},
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "id": 0,
  "provider": "mailgun",
  "category": "email",
  "active": true,
  "primary": true,
  "status": "pending",
  "connected_at": "2024-01-15T09:30:00Z",
  "last_tested_at": "2024-01-15T09:30:00Z",
  "error_message": "string",
  "config_summary": {},
  "secret_hints": {},
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "missing_scopes": [
    "read_customers"
  ],
  "validation_errors": {}
}

Start Stripe App OAuth connect flow

POST
https://api.nitrosend.com/v1/my/integrations/stripe/connect

Returns the Nitrosend Stripe App install link for the authenticated account and brand. The link carries a signed state and the API callback URI; installing the app grants Nitrosend read access to customers, subscriptions, invoices, charges, refunds and events. Pass mode: test for the app's test-mode install link. No keys are pasted; tokens are refreshed server-side. Events for connected accounts arrive on /hooks/stripe_apps, isolated from Nitrosend billing webhooks at /hooks/stripe.

Body

application/json
stripeobject
Show child attributes
modestringlivetestlive

Response

200OKobject

OAuth authorize URL

401UnauthorizedError

Not authenticated

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Start Stripe App OAuth connect flow
curl -X POST 'https://api.nitrosend.com/v1/my/integrations/stripe/connect' \
  -H 'Content-Type: application/json' \
  -d '{
    "stripe": {
      "mode": "live"
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/integrations/stripe/connect', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "stripe": {
        "mode": "live"
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "stripe": {
    "mode": "live"
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/integrations/stripe/connect', json=payload)
data = response.json()
Request Body
{
  "stripe": {
    "mode": "live"
  }
}
{
  "authorize_url": "https://example.com"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Public Stripe App install entry

GET
https://api.nitrosend.com/integrations/stripe/install

The Stripe App Marketplace install URL. Sets a nonce cookie and redirects to the Stripe App install link for the requested mode. The callback provisions a Nitrosend account for a new email, or asks an existing user to sign in and connect from the integrations page.

Parameters

modestringlivetestlivequery

Response

302Found

Redirect to the Stripe App install link

404Not Found

The Stripe App is not configured

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Public Stripe App install entry
curl -X GET 'https://api.nitrosend.com/integrations/stripe/install'
const response = await fetch('https://api.nitrosend.com/integrations/stripe/install', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/integrations/stripe/install')
data = response.json()

Stripe App OAuth callback endpoint

GET
https://api.nitrosend.com/integrations/stripe/callback

Public callback endpoint used by Stripe after the app is installed. Verifies signed state, exchanges the auth code with the mode-matched developer key, persists the integration and enqueues initial sync. A signed-in connect renders the countdown page; the public install door redirects into the app (new account) or to sign in (existing account).

Parameters

codestringquery
statestringquery
errorstringquery
error_descriptionstringquery

Response

200OKstring

OAuth callback processed (HTML)

302Found

Install door redirect into the app or to sign in

400Bad Requeststring

Invalid callback request

422Unprocessable Entitystring

OAuth exchange failure

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Stripe App OAuth callback endpoint
curl -X GET 'https://api.nitrosend.com/integrations/stripe/callback'
const response = await fetch('https://api.nitrosend.com/integrations/stripe/callback', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/integrations/stripe/callback')
data = response.json()
string
string
string

Attio OAuth callback endpoint

GET
https://api.nitrosend.com/integrations/attio/callback

Public callback endpoint used by Attio after user authorization. Verifies signed state, exchanges auth code, and finalizes Attio integration connection.

Parameters

codestringquery
statestringquery
errorstringquery
error_descriptionstringquery

Response

200OKstring

OAuth callback processed (HTML)

400Bad Requeststring

Invalid callback request

422Unprocessable Entitystring

OAuth exchange or webhook provisioning failure

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Attio OAuth callback endpoint
curl -X GET 'https://api.nitrosend.com/integrations/attio/callback'
const response = await fetch('https://api.nitrosend.com/integrations/attio/callback', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/integrations/attio/callback')
data = response.json()
string
string
string

HubSpot OAuth callback endpoint

GET
https://api.nitrosend.com/integrations/hubspot/callback

Public callback endpoint used by HubSpot after user authorization. Verifies signed state, exchanges auth code, persists the integration, and enqueues initial sync.

Parameters

codestringquery
statestringquery
errorstringquery
error_descriptionstringquery

Response

200OKstring

OAuth callback processed (HTML)

400Bad Requeststring

Invalid callback request

422Unprocessable Entitystring

OAuth exchange failure

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

HubSpot OAuth callback endpoint
curl -X GET 'https://api.nitrosend.com/integrations/hubspot/callback'
const response = await fetch('https://api.nitrosend.com/integrations/hubspot/callback', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/integrations/hubspot/callback')
data = response.json()
string
string
string

Shopify OAuth callback endpoint

GET
https://api.nitrosend.com/integrations/shopify/callback

Public callback endpoint used by Shopify after user authorization. Verifies signed state, resolves the Shopify app from that signed state, verifies the app-specific OAuth HMAC, exchanges the auth code, persists the integration and app key, and enqueues initial sync.

Parameters

codestringquery
statestringquery
shopstringquery
hmacstringquery
timestampstringquery
errorstringquery
error_descriptionstringquery

Response

200OKstring

OAuth callback processed (HTML)

400Bad Requeststring

Invalid callback request

422Unprocessable Entitystring

OAuth exchange failure

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Shopify OAuth callback endpoint
curl -X GET 'https://api.nitrosend.com/integrations/shopify/callback'
const response = await fetch('https://api.nitrosend.com/integrations/shopify/callback', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/integrations/shopify/callback')
data = response.json()
string
string
string

Receive a Stripe App event for a connected account

POST
https://api.nitrosend.com/hooks/stripe_apps

Events from every Stripe account that installed the Nitrosend app, delivered to the platform's connected-account webhook endpoint. The signature is verified with the app endpoint secret (live or test), the connection is resolved from account and livemode, and the event is processed on that integration's execution lane. Events for accounts that are not connected are acknowledged and dropped.

Body

application/json
object

Parameters

Stripe-Signaturestringrequiredheader

Response

200OK

Verified event acknowledged

403Forbidden

Invalid signature or unconfigured secret

500Internal Server Error

Verified event could not be enqueued

Receive a Stripe App event for a connected account
curl -X POST 'https://api.nitrosend.com/hooks/stripe_apps' \
  -H 'Content-Type: application/json' \
  -d '{}'
const response = await fetch('https://api.nitrosend.com/hooks/stripe_apps', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
});

const data = await response.json();
import requests

payload = {}

response = requests.post('https://api.nitrosend.com/hooks/stripe_apps', json=payload)
data = response.json()
Request Body
{}

Receive an App Store Shopify webhook

POST
https://api.nitrosend.com/hooks/shopify/events

Uses the App Store app credentials when no app key is present.

Body

application/json
object

Parameters

X-Shopify-Hmac-Sha256stringrequiredheader
X-Shopify-Shop-Domainstringrequiredheader
X-Shopify-Topicstringrequiredheader

Response

200OK

Verified webhook acknowledged

400Bad Request

Invalid JSON payload

401Unauthorized

Invalid App Store HMAC

500Internal Server Error

Verified webhook could not be applied

Receive an App Store Shopify webhook
curl -X POST 'https://api.nitrosend.com/hooks/shopify/events' \
  -H 'Content-Type: application/json' \
  -d '{}'
const response = await fetch('https://api.nitrosend.com/hooks/shopify/events', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
});

const data = await response.json();
import requests

payload = {}

response = requests.post('https://api.nitrosend.com/hooks/shopify/events', json=payload)
data = response.json()
Request Body
{}

Receive a merchant-managed Shopify webhook

POST
https://api.nitrosend.com/hooks/shopify/merchant/events

Resolves only active merchant-managed connections from the Shopify shop header and verifies the raw request body with that connection's encrypted client secret before parsing. Unknown shops, ambiguous ownership, missing secrets, and invalid signatures return the same response. Shopify Billing API topics are never processed on this route.

Body

application/json
object

Parameters

X-Shopify-Hmac-Sha256stringrequiredheader
X-Shopify-Shop-Domainstringrequiredheader
X-Shopify-Topicstringrequiredheader
X-Shopify-Webhook-Idstringheader

Response

200OK

Verified supported webhook processed or unsupported topic safely acknowledged

400Bad Request

Verified supported webhook contained invalid JSON

401Unauthorized

Webhook could not be authenticated

500Internal Server Error

Verified webhook could not be applied

Receive a merchant-managed Shopify webhook
curl -X POST 'https://api.nitrosend.com/hooks/shopify/merchant/events' \
  -H 'Content-Type: application/json' \
  -d '{}'
const response = await fetch('https://api.nitrosend.com/hooks/shopify/merchant/events', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
});

const data = await response.json();
import requests

payload = {}

response = requests.post('https://api.nitrosend.com/hooks/shopify/merchant/events', json=payload)
data = response.json()
Request Body
{}

Receive a Shopify webhook for a named app

POST
https://api.nitrosend.com/hooks/shopify/events/{app_key}

Body

application/json
object

Parameters

app_keystringcustomrequiredpath
X-Shopify-Hmac-Sha256stringrequiredheader
X-Shopify-Shop-Domainstringrequiredheader
X-Shopify-Topicstringrequiredheader

Response

200OK

Verified webhook acknowledged

400Bad Request

Invalid JSON payload

401Unauthorized

Invalid app-specific HMAC

500Internal Server Error

Verified webhook could not be applied

Receive a Shopify webhook for a named app
curl -X POST 'https://api.nitrosend.com/hooks/shopify/events/{app_key}' \
  -H 'Content-Type: application/json' \
  -d '{}'
const response = await fetch('https://api.nitrosend.com/hooks/shopify/events/{app_key}', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
});

const data = await response.json();
import requests

payload = {}

response = requests.post('https://api.nitrosend.com/hooks/shopify/events/{app_key}', json=payload)
data = response.json()
Request Body
{}

Open or resume the embedded Shopify app

POST
https://api.nitrosend.com/integrations/shopify/session

Verifies the Shopify App Bridge ID token in the Authorization header, exchanges it for an offline Shopify access token when installation is required, and provisions or resumes the Nitrosend account integration. Subsequent embedded requests continue to authenticate with fresh Shopify ID tokens.

Response

200OKobject

Embedded Shopify integration opened

401UnauthorizedError

Not authenticated

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Open or resume the embedded Shopify app
curl -X POST 'https://api.nitrosend.com/integrations/shopify/session'
const response = await fetch('https://api.nitrosend.com/integrations/shopify/session', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/integrations/shopify/session')
data = response.json()
{
  "integration_id": 0,
  "manage_url": "https://example.com",
  "requires_plan": true,
  "redirect_to": "string"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Reconcile Shopify App Pricing after plan management

GET
https://api.nitrosend.com/integrations/shopify/billing/callback

Parameters

shopstringrequiredquery

Response

302Found

Redirect back to the app in Shopify Admin

400Bad Request

Invalid Shopify shop domain

Reconcile Shopify App Pricing after plan management
curl -X GET 'https://api.nitrosend.com/integrations/shopify/billing/callback'
const response = await fetch('https://api.nitrosend.com/integrations/shopify/billing/callback', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/integrations/shopify/billing/callback')
data = response.json()

Brands

Brand context plus Brand Kit identity, theme, and per-brand configuration

List brands (paginated)

GET
https://api.nitrosend.com/v1/my/brands

Parameters

pageinteger1query
perinteger<= 100100query

Response

200OKArray<Brand>

All brands for the account

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List brands (paginated)
curl -X GET 'https://api.nitrosend.com/v1/my/brands'
const response = await fetch('https://api.nitrosend.com/v1/my/brands', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/brands')
data = response.json()
200
[
  {
    "id": 0,
    "sid": "string",
    "account_id": 0,
    "brand_color": "string",
    "text_color": "string",
    "bg_color": "string",
    "radius": 0,
    "spacing_density": "compact",
    "font_heading": "string",
    "font_body": "string",
    "heading_size": 12,
    "body_size": 12,
    "brand_document": "string",
    "company_description": "string",
    "default_header": {},
    "default_footer": {},
    "default_theme": {},
    "physical_address": "string",
    "company_name": "string",
    "source_url": "string",
    "last_scraped_at": "2024-01-15T09:30:00Z",
    "links": [
      {
        "url": "string",
        "icon": "string",
        "title": "string"
      }
    ],
    "logo": "string",
    "complete": true,
    "email_from_name": "string",
    "email_from_email": "string",
    "email_reply_to": "string",
    "from_email_domain_status": "blank",
    "effective_from_email": "user@example.com",
    "effective_reply_to": "user@example.com",
    "effective_sending_domain": "string",
    "effective_source_email": "user@example.com",
    "sender_configured": true,
    "email_view_online": true,
    "email_track_opens": true,
    "email_track_clicks": true,
    "test_email_recipients": [
      "user@example.com"
    ],
    "onboarding_state": {},
    "onboarding": {
      "steps": {},
      "progress": {
        "completed": 0,
        "total": 0
      }
    },
    "domain_verified": true,
    "can_send": true,
    "brand_subdomain": {
      "namespace_status": "unreserved",
      "status": "brand_identity_required",
      "ready": true,
      "selected": true,
      "preparation_required": true,
      "from_email": "user@example.com",
      "fqdn": "string",
      "apex": "string",
      "local_part": "string",
      "local_part_editable": true,
      "fqdn_changeable": false,
      "suggested_subdomain": "string"
    },
    "byo_routing": {
      "mismatch": true,
      "provider": "string",
      "bypassing_domains": [
        "string"
      ],
      "message": "string"
    },
    "subscribed_contacts_count": 0,
    "logo_url": "https://example.com",
    "screenshot_url": "https://example.com",
    "capabilities": {},
    "sms_provisioned": true,
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]

Create a brand

POST
https://api.nitrosend.com/v1/my/brands

Body

application/json
namestring

Internal brand name; mirrors company_name when company_name is omitted

brand_colorstring
text_colorstring
bg_colorstring
radiusinteger | null[0, 64]
spacing_densitystring | nullcompactnormalspacious
font_headingstring
font_bodystring
heading_sizeinteger | null[12, 48]
body_sizeinteger | null[12, 20]
brand_documentstring | null
company_descriptionstring
physical_addressstring
company_namestring
logostring

Signed blob ID or URL

email_from_namestring
email_from_emailstring<email>
email_reply_tostring<email>
email_view_onlineboolean
email_track_opensboolean

Inject the open-tracking pixel into this brand's emails.

email_track_clicksboolean

Rewrite this brand's links for click tracking.

test_email_recipientsArray<string>
linksArray<object>
Show child attributes
urlstring<uri>
iconstring
titlestring
default_headerobject
default_footerobject
default_themeobject

Response

201CreatedBrand

Brand created

422Unprocessable Entityobject | Error & object

Brand limit reached or validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create a brand
curl -X POST 'https://api.nitrosend.com/v1/my/brands' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string",
    "brand_color": "string",
    "text_color": "string",
    "bg_color": "string",
    "radius": 0,
    "spacing_density": "compact",
    "font_heading": "string",
    "font_body": "string",
    "heading_size": 12,
    "body_size": 12,
    "brand_document": "string",
    "company_description": "string",
    "physical_address": "string",
    "company_name": "string",
    "logo": "string",
    "email_from_name": "string",
    "email_from_email": "user@example.com",
    "email_reply_to": "user@example.com",
    "email_view_online": true,
    "email_track_opens": true,
    "email_track_clicks": true,
    "test_email_recipients": [
      "user@example.com"
    ],
    "links": [
      {
        "url": "https://example.com",
        "icon": "string",
        "title": "string"
      }
    ],
    "default_header": {},
    "default_footer": {},
    "default_theme": {}
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/brands', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string",
      "brand_color": "string",
      "text_color": "string",
      "bg_color": "string",
      "radius": 0,
      "spacing_density": "compact",
      "font_heading": "string",
      "font_body": "string",
      "heading_size": 12,
      "body_size": 12,
      "brand_document": "string",
      "company_description": "string",
      "physical_address": "string",
      "company_name": "string",
      "logo": "string",
      "email_from_name": "string",
      "email_from_email": "user@example.com",
      "email_reply_to": "user@example.com",
      "email_view_online": true,
      "email_track_opens": true,
      "email_track_clicks": true,
      "test_email_recipients": [
        "user@example.com"
      ],
      "links": [
        {
          "url": "https://example.com",
          "icon": "string",
          "title": "string"
        }
      ],
      "default_header": {},
      "default_footer": {},
      "default_theme": {}
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string",
  "brand_color": "string",
  "text_color": "string",
  "bg_color": "string",
  "radius": 0,
  "spacing_density": "compact",
  "font_heading": "string",
  "font_body": "string",
  "heading_size": 12,
  "body_size": 12,
  "brand_document": "string",
  "company_description": "string",
  "physical_address": "string",
  "company_name": "string",
  "logo": "string",
  "email_from_name": "string",
  "email_from_email": "user@example.com",
  "email_reply_to": "user@example.com",
  "email_view_online": True,
  "email_track_opens": True,
  "email_track_clicks": True,
  "test_email_recipients": [
    "user@example.com"
  ],
  "links": [
    {
      "url": "https://example.com",
      "icon": "string",
      "title": "string"
    }
  ],
  "default_header": {},
  "default_footer": {},
  "default_theme": {}
}

response = requests.post('https://api.nitrosend.com/v1/my/brands', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "brand_color": "string",
  "text_color": "string",
  "bg_color": "string",
  "radius": 0,
  "spacing_density": "compact",
  "font_heading": "string",
  "font_body": "string",
  "heading_size": 12,
  "body_size": 12,
  "brand_document": "string",
  "company_description": "string",
  "physical_address": "string",
  "company_name": "string",
  "logo": "string",
  "email_from_name": "string",
  "email_from_email": "user@example.com",
  "email_reply_to": "user@example.com",
  "email_view_online": true,
  "email_track_opens": true,
  "email_track_clicks": true,
  "test_email_recipients": [
    "user@example.com"
  ],
  "links": [
    {
      "url": "https://example.com",
      "icon": "string",
      "title": "string"
    }
  ],
  "default_header": {},
  "default_footer": {},
  "default_theme": {}
}
{
  "id": 0,
  "sid": "string",
  "account_id": 0,
  "brand_color": "string",
  "text_color": "string",
  "bg_color": "string",
  "radius": 0,
  "spacing_density": "compact",
  "font_heading": "string",
  "font_body": "string",
  "heading_size": 12,
  "body_size": 12,
  "brand_document": "string",
  "company_description": "string",
  "default_header": {},
  "default_footer": {},
  "default_theme": {},
  "physical_address": "string",
  "company_name": "string",
  "source_url": "string",
  "last_scraped_at": "2024-01-15T09:30:00Z",
  "links": [
    {
      "url": "string",
      "icon": "string",
      "title": "string"
    }
  ],
  "logo": "string",
  "complete": true,
  "email_from_name": "string",
  "email_from_email": "string",
  "email_reply_to": "string",
  "from_email_domain_status": "blank",
  "effective_from_email": "user@example.com",
  "effective_reply_to": "user@example.com",
  "effective_sending_domain": "string",
  "effective_source_email": "user@example.com",
  "sender_configured": true,
  "email_view_online": true,
  "email_track_opens": true,
  "email_track_clicks": true,
  "test_email_recipients": [
    "user@example.com"
  ],
  "onboarding_state": {},
  "onboarding": {
    "steps": {},
    "progress": {
      "completed": 0,
      "total": 0
    }
  },
  "domain_verified": true,
  "can_send": true,
  "brand_subdomain": {
    "namespace_status": "unreserved",
    "status": "brand_identity_required",
    "ready": true,
    "selected": true,
    "preparation_required": true,
    "from_email": "user@example.com",
    "fqdn": "string",
    "apex": "string",
    "local_part": "string",
    "local_part_editable": true,
    "fqdn_changeable": false,
    "suggested_subdomain": "string"
  },
  "byo_routing": {
    "mismatch": true,
    "provider": "string",
    "bypassing_domains": [
      "string"
    ],
    "message": "string"
  },
  "subscribed_contacts_count": 0,
  "logo_url": "https://example.com",
  "screenshot_url": "https://example.com",
  "capabilities": {},
  "sms_provisioned": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "error": true,
  "code": "brand_limit_reached",
  "message": "string"
}

Get a brand

GET
https://api.nitrosend.com/v1/my/brands/{sid}

Parameters

sidstringrequiredpath

Brand secure identifier

Response

200OKBrand

Brand

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get a brand
curl -X GET 'https://api.nitrosend.com/v1/my/brands/{sid}'
const response = await fetch('https://api.nitrosend.com/v1/my/brands/{sid}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/brands/{sid}')
data = response.json()
{
  "id": 0,
  "sid": "string",
  "account_id": 0,
  "brand_color": "string",
  "text_color": "string",
  "bg_color": "string",
  "radius": 0,
  "spacing_density": "compact",
  "font_heading": "string",
  "font_body": "string",
  "heading_size": 12,
  "body_size": 12,
  "brand_document": "string",
  "company_description": "string",
  "default_header": {},
  "default_footer": {},
  "default_theme": {},
  "physical_address": "string",
  "company_name": "string",
  "source_url": "string",
  "last_scraped_at": "2024-01-15T09:30:00Z",
  "links": [
    {
      "url": "string",
      "icon": "string",
      "title": "string"
    }
  ],
  "logo": "string",
  "complete": true,
  "email_from_name": "string",
  "email_from_email": "string",
  "email_reply_to": "string",
  "from_email_domain_status": "blank",
  "effective_from_email": "user@example.com",
  "effective_reply_to": "user@example.com",
  "effective_sending_domain": "string",
  "effective_source_email": "user@example.com",
  "sender_configured": true,
  "email_view_online": true,
  "email_track_opens": true,
  "email_track_clicks": true,
  "test_email_recipients": [
    "user@example.com"
  ],
  "onboarding_state": {},
  "onboarding": {
    "steps": {},
    "progress": {
      "completed": 0,
      "total": 0
    }
  },
  "domain_verified": true,
  "can_send": true,
  "brand_subdomain": {
    "namespace_status": "unreserved",
    "status": "brand_identity_required",
    "ready": true,
    "selected": true,
    "preparation_required": true,
    "from_email": "user@example.com",
    "fqdn": "string",
    "apex": "string",
    "local_part": "string",
    "local_part_editable": true,
    "fqdn_changeable": false,
    "suggested_subdomain": "string"
  },
  "byo_routing": {
    "mismatch": true,
    "provider": "string",
    "bypassing_domains": [
      "string"
    ],
    "message": "string"
  },
  "subscribed_contacts_count": 0,
  "logo_url": "https://example.com",
  "screenshot_url": "https://example.com",
  "capabilities": {},
  "sms_provisioned": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Delete a brand

DELETE
https://api.nitrosend.com/v1/my/brands/{sid}

Parameters

sidstringrequiredpath

Brand secure identifier

forcestringtruequery

Must be true to delete a brand that has queued messages or scheduled/live campaigns.

Response

200OKBrand

Deleted brand

409Conflictobject

Brand has active sends and requires explicit force confirmation

422Unprocessable EntityError

Cannot delete the only brand

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Delete a brand
curl -X DELETE 'https://api.nitrosend.com/v1/my/brands/{sid}'
const response = await fetch('https://api.nitrosend.com/v1/my/brands/{sid}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/brands/{sid}')
data = response.json()
{
  "id": 0,
  "sid": "string",
  "account_id": 0,
  "brand_color": "string",
  "text_color": "string",
  "bg_color": "string",
  "radius": 0,
  "spacing_density": "compact",
  "font_heading": "string",
  "font_body": "string",
  "heading_size": 12,
  "body_size": 12,
  "brand_document": "string",
  "company_description": "string",
  "default_header": {},
  "default_footer": {},
  "default_theme": {},
  "physical_address": "string",
  "company_name": "string",
  "source_url": "string",
  "last_scraped_at": "2024-01-15T09:30:00Z",
  "links": [
    {
      "url": "string",
      "icon": "string",
      "title": "string"
    }
  ],
  "logo": "string",
  "complete": true,
  "email_from_name": "string",
  "email_from_email": "string",
  "email_reply_to": "string",
  "from_email_domain_status": "blank",
  "effective_from_email": "user@example.com",
  "effective_reply_to": "user@example.com",
  "effective_sending_domain": "string",
  "effective_source_email": "user@example.com",
  "sender_configured": true,
  "email_view_online": true,
  "email_track_opens": true,
  "email_track_clicks": true,
  "test_email_recipients": [
    "user@example.com"
  ],
  "onboarding_state": {},
  "onboarding": {
    "steps": {},
    "progress": {
      "completed": 0,
      "total": 0
    }
  },
  "domain_verified": true,
  "can_send": true,
  "brand_subdomain": {
    "namespace_status": "unreserved",
    "status": "brand_identity_required",
    "ready": true,
    "selected": true,
    "preparation_required": true,
    "from_email": "user@example.com",
    "fqdn": "string",
    "apex": "string",
    "local_part": "string",
    "local_part_editable": true,
    "fqdn_changeable": false,
    "suggested_subdomain": "string"
  },
  "byo_routing": {
    "mismatch": true,
    "provider": "string",
    "bypassing_domains": [
      "string"
    ],
    "message": "string"
  },
  "subscribed_contacts_count": 0,
  "logo_url": "https://example.com",
  "screenshot_url": "https://example.com",
  "capabilities": {},
  "sms_provisioned": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "error": true,
  "code": "brand_has_active_sends",
  "active_sends": {
    "queued_messages": 0,
    "active_campaigns": 0
  },
  "deletion_safety": {
    "deletion_impact": {
      "contacts": 0,
      "campaigns": 0,
      "flows": 0,
      "templates": 0,
      "domains": 0,
      "messages": 0
    },
    "active_sends": {
      "queued_messages": 0,
      "active_campaigns": 0
    },
    "can_delete": true,
    "requires_force": true
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Update a brand

PATCH
https://api.nitrosend.com/v1/my/brands/{sid}

Body

application/json
namestring

Internal brand name; mirrors company_name when company_name is omitted

brand_colorstring
text_colorstring
bg_colorstring
radiusinteger | null[0, 64]
spacing_densitystring | nullcompactnormalspacious
font_headingstring
font_bodystring
heading_sizeinteger | null[12, 48]
body_sizeinteger | null[12, 20]
brand_documentstring | null
company_descriptionstring
physical_addressstring
company_namestring
logostring

Signed blob ID or URL

email_from_namestring
email_from_emailstring<email>
email_reply_tostring<email>
email_view_onlineboolean
email_track_opensboolean

Inject the open-tracking pixel into this brand's emails.

email_track_clicksboolean

Rewrite this brand's links for click tracking.

sender_identity_idinteger

Ready brand-owned email sending identity to select through the canonical sender-selection authority.

sender_local_partstring

Visible From local part for the selected sending identity.

test_email_recipientsArray<string>
linksArray<object>
Show child attributes
urlstring<uri>
iconstring
titlestring
default_headerobject
default_footerobject
default_themeobject

Parameters

sidstringrequiredpath

Brand secure identifier

Response

200OKBrand

Updated brand

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update a brand
curl -X PATCH 'https://api.nitrosend.com/v1/my/brands/{sid}' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string",
    "brand_color": "string",
    "text_color": "string",
    "bg_color": "string",
    "radius": 0,
    "spacing_density": "compact",
    "font_heading": "string",
    "font_body": "string",
    "heading_size": 12,
    "body_size": 12,
    "brand_document": "string",
    "company_description": "string",
    "physical_address": "string",
    "company_name": "string",
    "logo": "string",
    "email_from_name": "string",
    "email_from_email": "user@example.com",
    "email_reply_to": "user@example.com",
    "email_view_online": true,
    "email_track_opens": true,
    "email_track_clicks": true,
    "sender_identity_id": 0,
    "sender_local_part": "string",
    "test_email_recipients": [
      "user@example.com"
    ],
    "links": [
      {
        "url": "https://example.com",
        "icon": "string",
        "title": "string"
      }
    ],
    "default_header": {},
    "default_footer": {},
    "default_theme": {}
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/brands/{sid}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string",
      "brand_color": "string",
      "text_color": "string",
      "bg_color": "string",
      "radius": 0,
      "spacing_density": "compact",
      "font_heading": "string",
      "font_body": "string",
      "heading_size": 12,
      "body_size": 12,
      "brand_document": "string",
      "company_description": "string",
      "physical_address": "string",
      "company_name": "string",
      "logo": "string",
      "email_from_name": "string",
      "email_from_email": "user@example.com",
      "email_reply_to": "user@example.com",
      "email_view_online": true,
      "email_track_opens": true,
      "email_track_clicks": true,
      "sender_identity_id": 0,
      "sender_local_part": "string",
      "test_email_recipients": [
        "user@example.com"
      ],
      "links": [
        {
          "url": "https://example.com",
          "icon": "string",
          "title": "string"
        }
      ],
      "default_header": {},
      "default_footer": {},
      "default_theme": {}
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string",
  "brand_color": "string",
  "text_color": "string",
  "bg_color": "string",
  "radius": 0,
  "spacing_density": "compact",
  "font_heading": "string",
  "font_body": "string",
  "heading_size": 12,
  "body_size": 12,
  "brand_document": "string",
  "company_description": "string",
  "physical_address": "string",
  "company_name": "string",
  "logo": "string",
  "email_from_name": "string",
  "email_from_email": "user@example.com",
  "email_reply_to": "user@example.com",
  "email_view_online": True,
  "email_track_opens": True,
  "email_track_clicks": True,
  "sender_identity_id": 0,
  "sender_local_part": "string",
  "test_email_recipients": [
    "user@example.com"
  ],
  "links": [
    {
      "url": "https://example.com",
      "icon": "string",
      "title": "string"
    }
  ],
  "default_header": {},
  "default_footer": {},
  "default_theme": {}
}

response = requests.patch('https://api.nitrosend.com/v1/my/brands/{sid}', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "brand_color": "string",
  "text_color": "string",
  "bg_color": "string",
  "radius": 0,
  "spacing_density": "compact",
  "font_heading": "string",
  "font_body": "string",
  "heading_size": 12,
  "body_size": 12,
  "brand_document": "string",
  "company_description": "string",
  "physical_address": "string",
  "company_name": "string",
  "logo": "string",
  "email_from_name": "string",
  "email_from_email": "user@example.com",
  "email_reply_to": "user@example.com",
  "email_view_online": true,
  "email_track_opens": true,
  "email_track_clicks": true,
  "sender_identity_id": 0,
  "sender_local_part": "string",
  "test_email_recipients": [
    "user@example.com"
  ],
  "links": [
    {
      "url": "https://example.com",
      "icon": "string",
      "title": "string"
    }
  ],
  "default_header": {},
  "default_footer": {},
  "default_theme": {}
}
{
  "id": 0,
  "sid": "string",
  "account_id": 0,
  "brand_color": "string",
  "text_color": "string",
  "bg_color": "string",
  "radius": 0,
  "spacing_density": "compact",
  "font_heading": "string",
  "font_body": "string",
  "heading_size": 12,
  "body_size": 12,
  "brand_document": "string",
  "company_description": "string",
  "default_header": {},
  "default_footer": {},
  "default_theme": {},
  "physical_address": "string",
  "company_name": "string",
  "source_url": "string",
  "last_scraped_at": "2024-01-15T09:30:00Z",
  "links": [
    {
      "url": "string",
      "icon": "string",
      "title": "string"
    }
  ],
  "logo": "string",
  "complete": true,
  "email_from_name": "string",
  "email_from_email": "string",
  "email_reply_to": "string",
  "from_email_domain_status": "blank",
  "effective_from_email": "user@example.com",
  "effective_reply_to": "user@example.com",
  "effective_sending_domain": "string",
  "effective_source_email": "user@example.com",
  "sender_configured": true,
  "email_view_online": true,
  "email_track_opens": true,
  "email_track_clicks": true,
  "test_email_recipients": [
    "user@example.com"
  ],
  "onboarding_state": {},
  "onboarding": {
    "steps": {},
    "progress": {
      "completed": 0,
      "total": 0
    }
  },
  "domain_verified": true,
  "can_send": true,
  "brand_subdomain": {
    "namespace_status": "unreserved",
    "status": "brand_identity_required",
    "ready": true,
    "selected": true,
    "preparation_required": true,
    "from_email": "user@example.com",
    "fqdn": "string",
    "apex": "string",
    "local_part": "string",
    "local_part_editable": true,
    "fqdn_changeable": false,
    "suggested_subdomain": "string"
  },
  "byo_routing": {
    "mismatch": true,
    "provider": "string",
    "bypassing_domains": [
      "string"
    ],
    "message": "string"
  },
  "subscribed_contacts_count": 0,
  "logo_url": "https://example.com",
  "screenshot_url": "https://example.com",
  "capabilities": {},
  "sms_provisioned": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Reserve and prepare the Nitrosend sender

POST
https://api.nitrosend.com/v1/my/brands/{sid}/prepare_sending

Reserves the brand's Nitrosend address when the brand has none (using the optional chosen subdomain and local_part, otherwise the company-derived name) and idempotently materializes the brand-owned logical Domain and sending identity under the verified shared nitrosend.net root. The operation is database-only: it makes no DNS, Vercel, Cloudflare, or SES call and never sends or retains email. A brand that already owns a namespace gets it back unchanged; the body is ignored because an allocated name is immutable.

Body

application/json
subdomainstring

Chosen subdomain label under the hosted apex; validated by the same policy as company-derived names.

local_partstring

Local part for the sender address (defaults to hello).

Parameters

sidstringrequiredpath

Brand secure identifier

Response

200OKBrandSubdomainPreparationResponse

The brand-subdomain sender is ready

422Unprocessable EntityError

The account or Brand Kit is not eligible, or the chosen name was rejected. error_code is one of subdomain_taken, subdomain_unsafe, local_part_invalid, brand_identity_required, brand_identity_review_required, sender_identity_limit_reached, sender_identity_retired, brand_inactive, sending_paused, subscription_inactive, principal_email_missing.

503Service UnavailableError

The shared hosted-sender root is not release-ready; no identity or delivery state was written

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Reserve and prepare the Nitrosend sender
curl -X POST 'https://api.nitrosend.com/v1/my/brands/{sid}/prepare_sending' \
  -H 'Content-Type: application/json' \
  -d '{
    "subdomain": "string",
    "local_part": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/brands/{sid}/prepare_sending', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "subdomain": "string",
      "local_part": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "subdomain": "string",
  "local_part": "string"
}

response = requests.post('https://api.nitrosend.com/v1/my/brands/{sid}/prepare_sending', json=payload)
data = response.json()
Request Body
{
  "subdomain": "string",
  "local_part": "string"
}
{
  "status": "ready",
  "brand_subdomain": {
    "namespace_status": "unreserved",
    "status": "brand_identity_required",
    "ready": true,
    "selected": true,
    "preparation_required": true,
    "from_email": "user@example.com",
    "fqdn": "string",
    "apex": "string",
    "local_part": "string",
    "local_part_editable": true,
    "fqdn_changeable": false,
    "suggested_subdomain": "string"
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Check whether a Nitrosend address can be reserved

GET
https://api.nitrosend.com/v1/my/brands/{sid}/hosted_sender_availability

Advisory read for choosing the brand's Nitrosend address before it is reserved. Uses the same normaliser and uniqueness check as reservation, so the returned subdomain is exactly what prepare_sending would reserve. Never writes.

Parameters

sidstringrequiredpath

Brand secure identifier

subdomainstringrequiredquery

Requested subdomain label under the hosted apex

local_partstringquery

Requested local part, checked with the same policy reservation applies; omitted means the allocator's default.

Response

200OKHostedSenderAvailability

Availability result

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Check whether a Nitrosend address can be reserved
curl -X GET 'https://api.nitrosend.com/v1/my/brands/{sid}/hosted_sender_availability'
const response = await fetch('https://api.nitrosend.com/v1/my/brands/{sid}/hosted_sender_availability', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/brands/{sid}/hosted_sender_availability')
data = response.json()
{
  "subdomain": "string",
  "fqdn": "string",
  "available": true,
  "reason": "taken",
  "local_part": "string",
  "from_email": "string"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Get deletion safety for a brand

GET
https://api.nitrosend.com/v1/my/brands/{sid}/deletion_safety

Returns authoritative deletion impact counts and active-send state for the confirmation UI.

Parameters

sidstringrequiredpath

Brand secure identifier

Response

200OKBrandDeletionSafety

Brand deletion safety

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get deletion safety for a brand
curl -X GET 'https://api.nitrosend.com/v1/my/brands/{sid}/deletion_safety'
const response = await fetch('https://api.nitrosend.com/v1/my/brands/{sid}/deletion_safety', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/brands/{sid}/deletion_safety')
data = response.json()
{
  "deletion_impact": {
    "contacts": 0,
    "campaigns": 0,
    "flows": 0,
    "templates": 0,
    "domains": 0,
    "messages": 0
  },
  "active_sends": {
    "queued_messages": 0,
    "active_campaigns": 0
  },
  "can_delete": true,
  "requires_force": true
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Auto-detect brand from website

POST
https://api.nitrosend.com/v1/my/brands/{sid}/scrape

Enqueues a background job that scrapes the URL for brand colors, fonts, logo, and tone. Returns 202 immediately. Poll GET /v1/my/brands/{sid} for results.

Body

application/json
urlstring<uri>required

Parameters

sidstringrequiredpath

Brand secure identifier

Response

202Acceptedobject

Scrape job enqueued

422Unprocessable Entityobject

Invalid URL

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Auto-detect brand from website
curl -X POST 'https://api.nitrosend.com/v1/my/brands/{sid}/scrape' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://example.com"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/brands/{sid}/scrape', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "url": "https://example.com"
    }),
});

const data = await response.json();
import requests

payload = {
  "url": "https://example.com"
}

response = requests.post('https://api.nitrosend.com/v1/my/brands/{sid}/scrape', json=payload)
data = response.json()
Request Body
{
  "url": "https://example.com"
}
{
  "status": "scraping",
  "url": "https://example.com"
}
{
  "error": "string"
}

Get brand onboarding state

GET
https://api.nitrosend.com/v1/my/brands/{sid}/onboarding

Parameters

sidstringrequiredpath

Brand secure identifier

Response

200OKobject

Onboarding state for the brand

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get brand onboarding state
curl -X GET 'https://api.nitrosend.com/v1/my/brands/{sid}/onboarding'
const response = await fetch('https://api.nitrosend.com/v1/my/brands/{sid}/onboarding', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/brands/{sid}/onboarding')
data = response.json()
{
  "steps": {},
  "progress": {
    "completed": 0,
    "total": 0
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Complete a brand onboarding step

POST
https://api.nitrosend.com/v1/my/brands/{sid}/onboarding/steps

Body

application/json
stepstringbrand_kit_setupdomain_verifiedfirst_contactfirst_sendrequired

Parameters

sidstringrequiredpath

Brand secure identifier

Response

200OKobject

Updated onboarding state

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Complete a brand onboarding step
curl -X POST 'https://api.nitrosend.com/v1/my/brands/{sid}/onboarding/steps' \
  -H 'Content-Type: application/json' \
  -d '{
    "step": "brand_kit_setup"
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/brands/{sid}/onboarding/steps', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "step": "brand_kit_setup"
    }),
});

const data = await response.json();
import requests

payload = {
  "step": "brand_kit_setup"
}

response = requests.post('https://api.nitrosend.com/v1/my/brands/{sid}/onboarding/steps', json=payload)
data = response.json()
Request Body
{
  "step": "brand_kit_setup"
}
{
  "steps": {},
  "progress": {
    "completed": 0,
    "total": 0
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Get brand setup center state

GET
https://api.nitrosend.com/v1/my/brands/{sid}/setup_center

Parameters

sidstringrequiredpath

Brand secure identifier

Response

200OKSetupCenterPayload

Setup center state for the brand

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get brand setup center state
curl -X GET 'https://api.nitrosend.com/v1/my/brands/{sid}/setup_center'
const response = await fetch('https://api.nitrosend.com/v1/my/brands/{sid}/setup_center', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/brands/{sid}/setup_center')
data = response.json()
{
  "cards": [
    {
      "id": "brand_kit_scan",
      "complete": true,
      "acknowledged": true,
      "acknowledged_at": "2024-01-15T09:30:00Z"
    }
  ],
  "sections": {
    "required": [
      "string"
    ],
    "recommended": [
      "string"
    ]
  },
  "progress": {
    "completed": 0,
    "total": 0
  },
  "seen": true,
  "dismissed": true,
  "complete": true,
  "established": true
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Update brand setup center state

PATCH
https://api.nitrosend.com/v1/my/brands/{sid}/setup_center

Body

application/json

Provide one of seen, dismissed, or card.

seenboolean
dismissedboolean
cardstringbrand_kit_scandnsimport_subscribersconnect_agent
metadataobject

Parameters

sidstringrequiredpath

Brand secure identifier

Response

200OKSetupCenterPayload

Updated setup center state

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update brand setup center state
curl -X PATCH 'https://api.nitrosend.com/v1/my/brands/{sid}/setup_center' \
  -H 'Content-Type: application/json' \
  -d '{
    "seen": true,
    "dismissed": true,
    "card": "brand_kit_scan",
    "metadata": {}
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/brands/{sid}/setup_center', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "seen": true,
      "dismissed": true,
      "card": "brand_kit_scan",
      "metadata": {}
    }),
});

const data = await response.json();
import requests

payload = {
  "seen": True,
  "dismissed": True,
  "card": "brand_kit_scan",
  "metadata": {}
}

response = requests.patch('https://api.nitrosend.com/v1/my/brands/{sid}/setup_center', json=payload)
data = response.json()
Request Body
{
  "seen": true,
  "dismissed": true,
  "card": "brand_kit_scan",
  "metadata": {}
}
{
  "cards": [
    {
      "id": "brand_kit_scan",
      "complete": true,
      "acknowledged": true,
      "acknowledged_at": "2024-01-15T09:30:00Z"
    }
  ],
  "sections": {
    "required": [
      "string"
    ],
    "recommended": [
      "string"
    ]
  },
  "progress": {
    "completed": 0,
    "total": 0
  },
  "seen": true,
  "dismissed": true,
  "complete": true,
  "established": true
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

SavedViews

Saved table presets (filters + sort + columns) per surface

List saved views visible to the current user

GET
https://api.nitrosend.com/v1/my/saved_views

Returns all shared views in the current account plus the caller's own private views. Optionally filtered by surface.

Parameters

surfacestringcontactssendingactivityquery

Filter views by surface

pageinteger1query
limitinteger<= 10025query

Response

200OKArray<SavedView>

Saved views

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List saved views visible to the current user
curl -X GET 'https://api.nitrosend.com/v1/my/saved_views'
const response = await fetch('https://api.nitrosend.com/v1/my/saved_views', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/saved_views')
data = response.json()
200
[]

Create a saved view

POST
https://api.nitrosend.com/v1/my/saved_views

Creates a new saved view owned by the current user. Defaults to private visibility if not specified.

Body

application/json
surfacestringcontactssendingactivityrequired
namestringrequired
visibilitystringprivatesharedprivate
filtersSegmentFilterExpression
layoutSavedViewLayout | null

Table layout preset for contacts surface views. Only present when surface = contacts.

Show child attributes
columnsArray<string>

Ordered list of column keys to display

sortobject
Show child attributes
fieldstring

Column key to sort by

dirstringascdesc

Sort direction

Response

201CreatedSavedView

Saved view created

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create a saved view
curl -X POST 'https://api.nitrosend.com/v1/my/saved_views' \
  -H 'Content-Type: application/json' \
  -d '{
    "surface": "contacts",
    "name": "string",
    "visibility": "private",
    "layout": {
      "columns": [
        "string"
      ],
      "sort": {
        "field": "string",
        "dir": "asc"
      }
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/saved_views', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "surface": "contacts",
      "name": "string",
      "visibility": "private",
      "layout": {
        "columns": [
          "string"
        ],
        "sort": {
          "field": "string",
          "dir": "asc"
        }
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "surface": "contacts",
  "name": "string",
  "visibility": "private",
  "layout": {
    "columns": [
      "string"
    ],
    "sort": {
      "field": "string",
      "dir": "asc"
    }
  }
}

response = requests.post('https://api.nitrosend.com/v1/my/saved_views', json=payload)
data = response.json()
Request Body
{
  "surface": "contacts",
  "name": "string",
  "visibility": "private",
  "layout": {
    "columns": [
      "string"
    ],
    "sort": {
      "field": "string",
      "dir": "asc"
    }
  }
}
422
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Delete a saved view

DELETE
https://api.nitrosend.com/v1/my/saved_views/{id}

Deletes a saved view. Allowed only for the creator or the account owner. Other members receive 403.

Parameters

idintegerrequiredpath

Response

200OKSavedView

Deleted saved view

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Delete a saved view
curl -X DELETE 'https://api.nitrosend.com/v1/my/saved_views/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/saved_views/{id}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://api.nitrosend.com/v1/my/saved_views/{id}')
data = response.json()
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Update a saved view

PATCH
https://api.nitrosend.com/v1/my/saved_views/{id}

Updates a saved view. Allowed only for the creator or the account owner. Other members receive 403.

Body

application/json
namestring
visibilitystringprivateshared
filtersSegmentFilterExpression
layoutSavedViewLayout | null

Table layout preset for contacts surface views. Only present when surface = contacts.

Show child attributes
columnsArray<string>

Ordered list of column keys to display

sortobject
Show child attributes
fieldstring

Column key to sort by

dirstringascdesc

Sort direction

Parameters

idintegerrequiredpath

Response

200OKSavedView

Updated saved view

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Update a saved view
curl -X PATCH 'https://api.nitrosend.com/v1/my/saved_views/{id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "string",
    "visibility": "private",
    "layout": {
      "columns": [
        "string"
      ],
      "sort": {
        "field": "string",
        "dir": "asc"
      }
    }
  }'
const response = await fetch('https://api.nitrosend.com/v1/my/saved_views/{id}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "string",
      "visibility": "private",
      "layout": {
        "columns": [
          "string"
        ],
        "sort": {
          "field": "string",
          "dir": "asc"
        }
      }
    }),
});

const data = await response.json();
import requests

payload = {
  "name": "string",
  "visibility": "private",
  "layout": {
    "columns": [
      "string"
    ],
    "sort": {
      "field": "string",
      "dir": "asc"
    }
  }
}

response = requests.patch('https://api.nitrosend.com/v1/my/saved_views/{id}', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "visibility": "private",
  "layout": {
    "columns": [
      "string"
    ],
    "sort": {
      "field": "string",
      "dir": "asc"
    }
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Fork a saved view into a new private view

POST
https://api.nitrosend.com/v1/my/saved_views/{id}/fork

Clones an existing view (typically a shared view) into a new private view owned by the caller. The original is not modified.

Parameters

idintegerrequiredpath

Response

201CreatedSavedView

Forked saved view

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Fork a saved view into a new private view
curl -X POST 'https://api.nitrosend.com/v1/my/saved_views/{id}/fork'
const response = await fetch('https://api.nitrosend.com/v1/my/saved_views/{id}/fork', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/my/saved_views/{id}/fork')
data = response.json()
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Public

Unauthenticated public endpoints

Ingest a Shopify Web Pixel event

POST
https://api.nitrosend.com/v1/public/shopify/events

Browser-safe public collector for Shopify Web Pixel standard events. Requires a dedicated wpkey_live_... collector key. Secret nskey_live_... API keys are rejected. Pixel events are treated as funnel telemetry; verified Shopify webhooks remain authoritative for revenue checkout/purchase Events.

Body

application/json
event_idstringrequired
event_namestringproduct_viewedproduct_added_to_cartproduct_removed_from_cartrequired
customer_idstring
emailstring<email>
phonestring
propertiesobject

Response

202Acceptedobject

Event accepted, ignored, or dropped

401UnauthorizedError

Not authenticated

422Unprocessable EntityError & object

Validation failed

Authorization

bearerAuth
Ingest a Shopify Web Pixel event
curl -X POST 'https://api.nitrosend.com/v1/public/shopify/events' \
  -H 'Content-Type: application/json' \
  -d '{
    "event_id": "string",
    "event_name": "product_viewed",
    "customer_id": "string",
    "email": "user@example.com",
    "phone": "string",
    "properties": {}
  }'
const response = await fetch('https://api.nitrosend.com/v1/public/shopify/events', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "event_id": "string",
      "event_name": "product_viewed",
      "customer_id": "string",
      "email": "user@example.com",
      "phone": "string",
      "properties": {}
    }),
});

const data = await response.json();
import requests

payload = {
  "event_id": "string",
  "event_name": "product_viewed",
  "customer_id": "string",
  "email": "user@example.com",
  "phone": "string",
  "properties": {}
}

response = requests.post('https://api.nitrosend.com/v1/public/shopify/events', json=payload)
data = response.json()
Request Body
{
  "event_id": "string",
  "event_name": "product_viewed",
  "customer_id": "string",
  "email": "user@example.com",
  "phone": "string",
  "properties": {}
}
{
  "ok": true,
  "outcome": "captured",
  "event_id": 0
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Read anonymous scan, brand review, or generated draft status

GET
https://api.nitrosend.com/v1/public/flow_demo

Parameters

X-Flow-Demo-Tokenstringrequiredheader

Response

200OKobject

Current demo stage and its available review or draft data

422Unprocessable Entity

Missing or expired demo token

Read anonymous scan, brand review, or generated draft status
curl -X GET 'https://api.nitrosend.com/v1/public/flow_demo'
const response = await fetch('https://api.nitrosend.com/v1/public/flow_demo', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/public/flow_demo')
data = response.json()
200
{}

Start an anonymous brand scan for a flow demo

POST
https://api.nitrosend.com/v1/public/flow_demo

Creates a short-lived isolated demo workspace, not a visitor account. Rate limited by IP.

Body

application/json
domainstringrequired
goalstringrequired

Response

202Acceptedobject

Scan started

422Unprocessable Entity

Invalid or private website URL or goal

429Too Many Requests

Demo start rate limit reached

Start an anonymous brand scan for a flow demo
curl -X POST 'https://api.nitrosend.com/v1/public/flow_demo' \
  -H 'Content-Type: application/json' \
  -d '{
    "domain": "string",
    "goal": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/public/flow_demo', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "domain": "string",
      "goal": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "domain": "string",
  "goal": "string"
}

response = requests.post('https://api.nitrosend.com/v1/public/flow_demo', json=payload)
data = response.json()
Request Body
{
  "domain": "string",
  "goal": "string"
}
202
{
  "token": "string",
  "status": "scanning"
}

Keep selected scanned Brand Kit fields

POST
https://api.nitrosend.com/v1/public/flow_demo/review

Body

application/json
fieldsobjectrequired
include_logoboolean

Parameters

X-Flow-Demo-Tokenstringrequiredheader

Response

200OK

Reviewed brand is ready for flow generation

422Unprocessable Entity

Scan is incomplete or selected field was not offered

Keep selected scanned Brand Kit fields
curl -X POST 'https://api.nitrosend.com/v1/public/flow_demo/review' \
  -H 'Content-Type: application/json' \
  -d '{
    "fields": {},
    "include_logo": true
  }'
const response = await fetch('https://api.nitrosend.com/v1/public/flow_demo/review', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "fields": {},
      "include_logo": true
    }),
});

const data = await response.json();
import requests

payload = {
  "fields": {},
  "include_logo": True
}

response = requests.post('https://api.nitrosend.com/v1/public/flow_demo/review', json=payload)
data = response.json()
Request Body
{
  "fields": {},
  "include_logo": true
}

Generate a draft flow for the reviewed brand and goal

POST
https://api.nitrosend.com/v1/public/flow_demo/generate

Reuses the metered flow composer. Retrying the same demo returns the same inactive draft.

Parameters

X-Flow-Demo-Tokenstringrequiredheader

Response

200OKobject

Draft flow or in-progress generation status

422Unprocessable Entity

Brand review missing or generation failed

Generate a draft flow for the reviewed brand and goal
curl -X POST 'https://api.nitrosend.com/v1/public/flow_demo/generate'
const response = await fetch('https://api.nitrosend.com/v1/public/flow_demo/generate', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://api.nitrosend.com/v1/public/flow_demo/generate')
data = response.json()
200
{}

Get guest-safe Flow Builder steps and triggers

GET
https://api.nitrosend.com/v1/public/flow_demo/spec

Response

200OKobject

Flow editor schema restricted to guest-authorable actions

Get guest-safe Flow Builder steps and triggers
curl -X GET 'https://api.nitrosend.com/v1/public/flow_demo/spec'
const response = await fetch('https://api.nitrosend.com/v1/public/flow_demo/spec', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/public/flow_demo/spec')
data = response.json()
200
{}

Get a canonical email template for guest editing

GET
https://api.nitrosend.com/v1/public/templates/{id}

Returns one known system catalog template as concrete, validated editor JSON. Catalog theme markers are resolved before the response. The response contains no account-specific data and does not create a saved template.

Parameters

idstringrequiredpath

Response

200OKPublicEmailCatalogTemplate

Canonical catalog template

404Not FoundError

Resource not found

Get a canonical email template for guest editing
curl -X GET 'https://api.nitrosend.com/v1/public/templates/{id}'
const response = await fetch('https://api.nitrosend.com/v1/public/templates/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/public/templates/{id}')
data = response.json()
{
  "id": "string",
  "name": "string",
  "category": "string",
  "tags": [
    "string"
  ],
  "description": "string",
  "subject": "string",
  "preheader": "string",
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  }
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Get the email editor schema for guest editing

GET
https://api.nitrosend.com/v1/public/templates/spec

Returns the canonical component and theme schema used by the email editor.

Response

200OKEmailComponentSpec

Email component schema

Get the email editor schema for guest editing
curl -X GET 'https://api.nitrosend.com/v1/public/templates/spec'
const response = await fetch('https://api.nitrosend.com/v1/public/templates/spec', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/public/templates/spec')
data = response.json()
200
{
  "version": 0,
  "design_guidelines": "string",
  "components": [
    {
      "type": "string",
      "description": "string",
      "tips": [
        "string"
      ],
      "props": {}
    }
  ],
  "style_attributes": [
    {
      "key": "string",
      "label": "string",
      "type": "color",
      "theme_fallback": "string",
      "description": "string",
      "min": 0,
      "max": 0,
      "values": [
        "string"
      ],
      "target": {
        "el": "section",
        "attr": "string"
      }
    }
  ],
  "preview_document": {
    "parameter": "string",
    "description": "string",
    "example": {}
  },
  "variables": {},
  "filters": [
    {
      "name": "string",
      "syntax": "string",
      "description": "string"
    }
  ],
  "theme_attributes": [
    {
      "key": "string",
      "label": "string",
      "type": "color",
      "category": "color",
      "slot": "string",
      "surfaces": [
        "string"
      ],
      "min": 0,
      "max": 0,
      "values": [
        "string"
      ],
      "options": [
        {
          "value": "string",
          "label": "string",
          "description": "string"
        }
      ],
      "transform_table": {},
      "column": true,
      "storage": "string",
      "placeholder": "string",
      "value_resolver": "string",
      "server_owned": true,
      "description": "string"
    }
  ]
}

Create or update a public contact (website forms)

POST
https://api.nitrosend.com/v1/public/contacts

Public signup endpoint for website forms. Authenticate with a wpkey_live_… public key. Returns { ok: true } whether the contact is new or already subscribed; this preserves idempotency and avoids leaking which emails are on the list.

Use the brand's public key (wpkey_live_…). Secret keys (nskey_live_…) are rejected on this endpoint.

Body

application/json
emailstring<email>required

Subscriber email address.

list_idintegerrequired

ID of a contact list owned by the brand whose public key is presented.

first_namestring | null

Optional first name written to the contact.

last_namestring | null

Optional last name written to the contact.

phonestring | null

Optional E.164 phone number written to the SMS channel if provided.

sourcestring | null

Optional free-text label, e.g. "footer-form" or "/pricing", recorded against the signup.

dataobject | null

Optional bag of custom contact data. Reserved keys are silently dropped.

Response

201Createdobject

Contact accepted

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

429Too Many RequestsError

Rate limit exceeded

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Create or update a public contact (website forms)
curl -X POST 'https://api.nitrosend.com/v1/public/contacts' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "user@example.com",
    "list_id": 0,
    "first_name": "string",
    "last_name": "string",
    "phone": "string",
    "source": "string",
    "data": {}
  }'
const response = await fetch('https://api.nitrosend.com/v1/public/contacts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "email": "user@example.com",
      "list_id": 0,
      "first_name": "string",
      "last_name": "string",
      "phone": "string",
      "source": "string",
      "data": {}
    }),
});

const data = await response.json();
import requests

payload = {
  "email": "user@example.com",
  "list_id": 0,
  "first_name": "string",
  "last_name": "string",
  "phone": "string",
  "source": "string",
  "data": {}
}

response = requests.post('https://api.nitrosend.com/v1/public/contacts', json=payload)
data = response.json()
Request Body
{
  "email": "user@example.com",
  "list_id": 0,
  "first_name": "string",
  "last_name": "string",
  "phone": "string",
  "source": "string",
  "data": {}
}
{
  "ok": true
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Get available plans

GET
https://api.nitrosend.com/v1/app

Response

200OKobject

Active plans

Get available plans
curl -X GET 'https://api.nitrosend.com/v1/app'
const response = await fetch('https://api.nitrosend.com/v1/app', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/app')
data = response.json()
200
{
  "plans": [
    {
      "id": 0,
      "name": "string",
      "active": true,
      "probation_recipient_cap_24h": 0,
      "standard_recipient_cap_24h": 0,
      "trusted_recipient_cap_24h": 0,
      "entitlements": {
        "agent_inbox": {
          "enabled": true,
          "max_inboxes": 0,
          "inbound_messages_included": 0,
          "inbound_messages_metered": true,
          "inbound_message_overage_rate_cents": "string",
          "max_inbound_domains": 0,
          "max_apex_domains": 0,
          "apex_mx": true,
          "legacy_forwarding": true,
          "catch_all": true,
          "retention_days": 0,
          "advanced_queue_controls": true
        }
      }
    }
  ],
  "stripe_publishable_key": "string"
}

MCP

Model Context Protocol JSON-RPC endpoint and discovery

Probe the MCP OAuth endpoint

GET
https://api.nitrosend.com/mcp

Unauthenticated probes receive the RFC 9728 protected-resource metadata URL in WWW-Authenticate so OAuth clients can continue discovery. Authenticated requests receive 405 Method Not Allowed because this server does not offer a server-initiated event stream over GET. Use POST /mcp for MCP Streamable HTTP requests.

Response

401Unauthorizedobject

MCP authentication required

405Method Not Allowedobject

Authenticated GET is not supported by the MCP transport

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Probe the MCP OAuth endpoint
curl -X GET 'https://api.nitrosend.com/mcp'
const response = await fetch('https://api.nitrosend.com/mcp', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/mcp')
data = response.json()
{}
{}

MCP JSON-RPC endpoint

POST
https://api.nitrosend.com/mcp

JSON-RPC endpoint for the Nitrosend MCP server. Read nitro://account, nitro://config, or call nitro_get_status for bound account identity; there is no per-tool account override argument.

Body

application/json
object

Response

200OKobject

JSON-RPC response

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

MCP JSON-RPC endpoint
curl -X POST 'https://api.nitrosend.com/mcp' \
  -H 'Content-Type: application/json' \
  -d '{}'
const response = await fetch('https://api.nitrosend.com/mcp', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
});

const data = await response.json();
import requests

payload = {}

response = requests.post('https://api.nitrosend.com/mcp', json=payload)
data = response.json()
Request Body
{}
200
{}

Operator

Internal production support operations; requires an admin or staff API key

List the production customer-support queue

GET
https://api.nitrosend.com/v1/operator/support_requests

Requires an nskey_live_... API key owned by an admin or staff user. Browser JWTs are rejected.

Parameters

statusstringquery
due_onlybooleanfalsequery
account_idintegerquery
brand_idintegerquery
pageinteger1query
limitinteger<= 10025query

Response

200OKArray<OperatorSupportRequest>

Paginated support queue

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List the production customer-support queue
curl -X GET 'https://api.nitrosend.com/v1/operator/support_requests'
const response = await fetch('https://api.nitrosend.com/v1/operator/support_requests', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/operator/support_requests')
data = response.json()
[
  {
    "id": 0,
    "account_id": 0,
    "brand_id": 0,
    "subject": "string",
    "message": "string",
    "status": "open",
    "follow_up_at": "2024-01-15T09:30:00Z",
    "resolved_at": "2024-01-15T09:30:00Z",
    "last_replied_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Get one production support case

GET
https://api.nitrosend.com/v1/operator/support_requests/{id}

Parameters

idintegerrequiredpath

Response

200OKOperatorSupportCase

Support request, customer account, brand, and latest reply ledger state

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get one production support case
curl -X GET 'https://api.nitrosend.com/v1/operator/support_requests/{id}'
const response = await fetch('https://api.nitrosend.com/v1/operator/support_requests/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/operator/support_requests/{id}')
data = response.json()
{
  "support_request": {
    "id": 0,
    "account_id": 0,
    "brand_id": 0,
    "subject": "string",
    "message": "string",
    "status": "open",
    "follow_up_at": "2024-01-15T09:30:00Z",
    "resolved_at": "2024-01-15T09:30:00Z",
    "last_replied_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z",
    "support_transcript": "string",
    "support_transcript_truncated": true
  },
  "account": {},
  "brand": {},
  "latest_reply": {},
  "github_issue": {}
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Read bounded live diagnostics for a support case

GET
https://api.nitrosend.com/v1/operator/support_requests/{id}/diagnostics

Parameters

idintegerrequiredpath

Response

200OKobject

Current sending, DNS, campaign, and message evidence

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Read bounded live diagnostics for a support case
curl -X GET 'https://api.nitrosend.com/v1/operator/support_requests/{id}/diagnostics'
const response = await fetch('https://api.nitrosend.com/v1/operator/support_requests/{id}/diagnostics', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/operator/support_requests/{id}/diagnostics')
data = response.json()
{}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Persist a versioned customer reply draft

POST
https://api.nitrosend.com/v1/operator/support_requests/{id}/draft

Body

application/json
bodystringrequired
runx_receipt_idstring | null

Parameters

idintegerrequiredpath

Response

201CreatedOperatorReplyDraft

Draft persisted in the reply ledger

400Bad RequestError

Bad request

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Persist a versioned customer reply draft
curl -X POST 'https://api.nitrosend.com/v1/operator/support_requests/{id}/draft' \
  -H 'Content-Type: application/json' \
  -d '{
    "body": "string",
    "runx_receipt_id": "string"
  }'
const response = await fetch('https://api.nitrosend.com/v1/operator/support_requests/{id}/draft', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "body": "string",
      "runx_receipt_id": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "body": "string",
  "runx_receipt_id": "string"
}

response = requests.post('https://api.nitrosend.com/v1/operator/support_requests/{id}/draft', json=payload)
data = response.json()
Request Body
{
  "body": "string",
  "runx_receipt_id": "string"
}
{
  "status": "drafted",
  "support_request_id": 0,
  "thread_record_id": 0,
  "draft_version": 0,
  "draft_state": "string",
  "terminal_outcome": "string",
  "last_replied_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Send one current versioned customer reply

POST
https://api.nitrosend.com/v1/operator/support_requests/{id}/send_reply

Delivery is fail-closed and requires confirm: true; stale draft versions are rejected by the server ledger.

Body

application/json
thread_record_idintegerrequired
draft_versionintegerrequired
confirmbooleanrequired

Parameters

idintegerrequiredpath

Response

200OKOperatorReplyDraft

Reply delivered

400Bad RequestError

Bad request

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

422Unprocessable EntityError & object

Validation failed

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Send one current versioned customer reply
curl -X POST 'https://api.nitrosend.com/v1/operator/support_requests/{id}/send_reply' \
  -H 'Content-Type: application/json' \
  -d '{
    "thread_record_id": 0,
    "draft_version": 0,
    "confirm": true
  }'
const response = await fetch('https://api.nitrosend.com/v1/operator/support_requests/{id}/send_reply', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "thread_record_id": 0,
      "draft_version": 0,
      "confirm": true
    }),
});

const data = await response.json();
import requests

payload = {
  "thread_record_id": 0,
  "draft_version": 0,
  "confirm": True
}

response = requests.post('https://api.nitrosend.com/v1/operator/support_requests/{id}/send_reply', json=payload)
data = response.json()
Request Body
{
  "thread_record_id": 0,
  "draft_version": 0,
  "confirm": true
}
{
  "status": "drafted",
  "support_request_id": 0,
  "thread_record_id": 0,
  "draft_version": 0,
  "draft_state": "string",
  "terminal_outcome": "string",
  "last_replied_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "validation_errors": {}
}

Set the persistent support-case disposition

POST
https://api.nitrosend.com/v1/operator/support_requests/{id}/disposition

Body

application/json
statusstringopenwaitingresolvedrequired
confirmbooleantruerequired

Explicit confirmation of the disposition mutation.

follow_up_atstring<date-time>

Required only for waiting.

Parameters

idintegerrequiredpath

Response

200OKOperatorSupportRequest

Updated support request

400Bad RequestError

Bad request

401UnauthorizedError

Not authenticated

403ForbiddenError

Not authorized

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Set the persistent support-case disposition
curl -X POST 'https://api.nitrosend.com/v1/operator/support_requests/{id}/disposition' \
  -H 'Content-Type: application/json' \
  -d '{
    "status": "open",
    "confirm": true,
    "follow_up_at": "2024-01-15T09:30:00Z"
  }'
const response = await fetch('https://api.nitrosend.com/v1/operator/support_requests/{id}/disposition', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "status": "open",
      "confirm": true,
      "follow_up_at": "2024-01-15T09:30:00Z"
    }),
});

const data = await response.json();
import requests

payload = {
  "status": "open",
  "confirm": True,
  "follow_up_at": "2024-01-15T09:30:00Z"
}

response = requests.post('https://api.nitrosend.com/v1/operator/support_requests/{id}/disposition', json=payload)
data = response.json()
Request Body
{
  "status": "open",
  "confirm": true,
  "follow_up_at": "2024-01-15T09:30:00Z"
}
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "subject": "string",
  "message": "string",
  "status": "open",
  "follow_up_at": "2024-01-15T09:30:00Z",
  "resolved_at": "2024-01-15T09:30:00Z",
  "last_replied_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Chat Sessions

List persisted chat sessions

GET
https://api.nitrosend.com/v1/my/chat_sessions

Parameters

pageinteger1query
limitinteger<= 10025query

Response

200OKArray<ChatSession>

Paginated list of chat sessions

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

List persisted chat sessions
curl -X GET 'https://api.nitrosend.com/v1/my/chat_sessions'
const response = await fetch('https://api.nitrosend.com/v1/my/chat_sessions', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/chat_sessions')
data = response.json()
200
[
  {
    "id": 0,
    "account_id": 0,
    "brand_id": 0,
    "title": "string",
    "status": "active",
    "started_at": "2024-01-15T09:30:00Z",
    "last_message_at": "2024-01-15T09:30:00Z",
    "message_count": 0,
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
]

Get a persisted chat session with ordered messages

GET
https://api.nitrosend.com/v1/my/chat_sessions/{id}

Parameters

idintegerrequiredpath

Response

200OKChatSession & object

Chat session

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Get a persisted chat session with ordered messages
curl -X GET 'https://api.nitrosend.com/v1/my/chat_sessions/{id}'
const response = await fetch('https://api.nitrosend.com/v1/my/chat_sessions/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://api.nitrosend.com/v1/my/chat_sessions/{id}')
data = response.json()
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "title": "string",
  "status": "active",
  "started_at": "2024-01-15T09:30:00Z",
  "last_message_at": "2024-01-15T09:30:00Z",
  "message_count": 0,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "messages": [
    {
      "id": 0,
      "role": "user",
      "content": "string",
      "tool_calls": [
        {
          "id": "string",
          "name": "string",
          "input": {},
          "safe": true,
          "status": "pending",
          "approval_token": "string"
        }
      ],
      "actions": [
        {}
      ],
      "sequence": 0,
      "created_at": "2024-01-15T09:30:00Z"
    }
  ]
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Close an active persisted chat session

PATCH
https://api.nitrosend.com/v1/my/chat_sessions/{id}/close

Parameters

idintegerrequiredpath

Response

200OKChatSession

Closed chat session

404Not FoundError

Resource not found

Authorization

BearerAuthhttp (bearer)

Authentication scheme depends on the route:

  • Authenticated endpoints (/v1/my/*) accept a server API key (nskey_live_...), a Nitrosend JWT, or a verified Shopify App Bridge ID token for an active embedded installation. API key is checked first.
  • Public website-form endpoints (/v1/public/*) require a brand public key (wpkey_live_...). Secret keys (nskey_live_...) are rejected here so they can't be smuggled into browser code.

For accounts with multiple brands, include the X-Brand-SID header to scope requests to a specific brand. If omitted, the account's default brand is used. JWT requests can also include X-Account-ID to select an accessible account.

Close an active persisted chat session
curl -X PATCH 'https://api.nitrosend.com/v1/my/chat_sessions/{id}/close'
const response = await fetch('https://api.nitrosend.com/v1/my/chat_sessions/{id}/close', {
  method: 'PATCH',
});

const data = await response.json();
import requests

response = requests.patch('https://api.nitrosend.com/v1/my/chat_sessions/{id}/close')
data = response.json()
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "title": "string",
  "status": "active",
  "started_at": "2024-01-15T09:30:00Z",
  "last_message_at": "2024-01-15T09:30:00Z",
  "message_count": 0,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

Models

OperatorSupportRequest

object
idintegerrequired
account_idintegerrequired
brand_idintegerrequired
subjectstringrequired
messagestringrequired
statusstringopenwaitingresolvedrequired
follow_up_atstring<date-time> | null
resolved_atstring<date-time> | null
last_replied_atstring<date-time> | null
created_atstring<date-time>required
updated_atstring<date-time>required
Example
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "subject": "string",
  "message": "string",
  "status": "open",
  "follow_up_at": "2024-01-15T09:30:00Z",
  "resolved_at": "2024-01-15T09:30:00Z",
  "last_replied_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

OperatorSupportCase

object
support_requestOperatorSupportRequest & objectrequired
accountobjectrequired
brandobjectrequired
latest_replyobject | null
github_issueobject | null
Example
{
  "support_request": {
    "id": 0,
    "account_id": 0,
    "brand_id": 0,
    "subject": "string",
    "message": "string",
    "status": "open",
    "follow_up_at": "2024-01-15T09:30:00Z",
    "resolved_at": "2024-01-15T09:30:00Z",
    "last_replied_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z",
    "support_transcript": "string",
    "support_transcript_truncated": true
  },
  "account": {},
  "brand": {},
  "latest_reply": {},
  "github_issue": {}
}

OperatorReplyDraft

object
statusstringdraftedsentrequired
support_request_idintegerrequired
thread_record_idintegerrequired
draft_versionintegerrequired
draft_statestring
terminal_outcomestring | null
last_replied_atstring<date-time> | null
Example
{
  "status": "drafted",
  "support_request_id": 0,
  "thread_record_id": 0,
  "draft_version": 0,
  "draft_state": "string",
  "terminal_outcome": "string",
  "last_replied_at": "2024-01-15T09:30:00Z"
}

TimelineEntry

object

One normalised, whitelisted entry in a contact's unified timeline.

idstringrequired

Stable composite id, e.g. "event-123".

kindstringeventactivitylifecyclerequired
typestringrequired

Event/activity name, e.g. checkout, opened.

titlestringrequired

Human-readable label for the entry.

occurred_atstring<date-time>required
metaobjectrequired

Display-only extras (e.g. amount, resource_name). No internal fields.

Example
{
  "id": "string",
  "kind": "event",
  "type": "string",
  "title": "string",
  "occurred_at": "2024-01-15T09:30:00Z",
  "meta": {}
}

Error

object
capacity_recoveryDeliveryCapacityRecovery

Informational recovery at 80 percent used, exhaustion, or when a campaign exceeds remaining allowance. Never denies a send or promises that payment or verification bypasses safety. Actions come from the shared backend projection; only offer verification when new valid proof can improve standing.

Show child attributes
statestringapproachingreachedcampaign_exceeds_remainingrequired
reason_codestringsending_capacity_warningsending_capacity_reachedrequired
blocking_controlstringcommercial_capacityrequired
usage_percentinteger[0, 100]required
requested_quantityinteger>= 0
labelstringrequired
detailstringrequired
capacityDeliveryCapacityrequired
Show child attributes
sourcestringplanoperator_override
window_secondsinteger
statusstringknownunlimitednot_applicableunknowndegradedrequired
limitinteger | null>= 0required
reservedinteger | null>= 0required
acceptedinteger | null>= 0required
provider_unknowninteger | null>= 0required
remaininginteger | null>= 0required
upgrade_urlstring<uri>

Shareable account-specific plan link. Authentication and billing permissions still apply.

retry_atstring<date-time>

Recorded retry time, not a guarantee that delivery completes then.

recovery_actionDeliveryCapacityRecoveryActionrequired
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
recovery_actionsArray<DeliveryCapacityRecoveryAction>required
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
owner_actionDeliveryCapacityRecoveryActionrequired
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
recovery_actionobject

Context-specific recovery action, including sending capacity or prepaid funding recovery.

codeintegerrequired
messagestringrequired
errorbooleanrequired
error_codestring | null

Optional machine-readable error reason.

provisioning_idinteger | null

Existing provisioning row involved in a managed-account conflict.

retryableboolean

Whether retrying the same idempotent operation can succeed.

retry_atstring<date-time>

Earliest recommended retry time for a retryable failure.

Example
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

User

object
idinteger
first_namestring | null
last_namestring | null
emailstring<email>
mobilestring | null
country_codestring | null
time_zonestring | null
adminboolean
ui_login_countinteger

Capped three-state dashboard-login counter: 0 = the user has never logged into the app UI, 1 = the user is inside their first UI login, 2 = returning. Advances only on real dashboard logins (never on API key, MCP, or agent-connect authentication).

created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "first_name": "string",
  "last_name": "string",
  "email": "user@example.com",
  "mobile": "string",
  "country_code": "string",
  "time_zone": "string",
  "admin": true,
  "ui_login_count": 0,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

Impersonator

object
idinteger
emailstring<email>
namestring | null
Example
{
  "id": 0,
  "email": "user@example.com",
  "name": "string"
}

ImpersonationStatus

object
impersonatingbooleanrequired
impersonatorImpersonator | nullrequired
Example
{
  "impersonating": true,
  "impersonator": {
    "id": 0,
    "email": "user@example.com",
    "name": "string"
  }
}

ImpersonationExit

object
redirect_urlstring<uri>required
Example
{
  "redirect_url": "https://api.nitrosend.com/adm"
}

ManagedAccountLifecycleStatus

string
ManagedAccountLifecycleStatuspreparingawaiting_ownerpayment_requiredactivepayment_issueended
Example
"preparing"

ManagedAccountLifecycleStatusFilter

string
ManagedAccountLifecycleStatusFilterpreparingawaiting_ownerpayment_requiredactivepayment_issueendedneeds_setup
Example
"preparing"

ManagedAccountProvisioning

object
idintegerrequired
external_refstringrequired
sourcestringdashboardpartner_apirequired
statusManagedAccountLifecycleStatuspreparingawaiting_ownerpayment_requiredactivepayment_issueendedrequired
permission_setstringoperator_v1required
allowed_actionsArray<string>send_invitationresend_invitationsend_payment_reminderenterreleaserequired
managed_accountobjectrequired
Show child attributes
idintegerrequired
namestring | nullrequired
ownerobjectrequired
Show child attributes
emailstring<email>required
invitationobjectrequired
Show child attributes
expiredbooleanrequired
expires_atstring<date-time>required
deadline_atstring<date-time>required
notice_sent_atstring<date-time> | nullrequired
claimed_atstring<date-time> | nullrequired
reissues_remaininginteger[0, 3]required
created_atstring<date-time>required
updated_atstring<date-time>required
Example
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

ManagedAccountProvisioningCreated

object
idintegerrequired
external_refstringrequired
sourcestringdashboardpartner_apirequired
statusManagedAccountLifecycleStatuspreparingawaiting_ownerpayment_requiredactivepayment_issueendedrequired
permission_setstringoperator_v1required
allowed_actionsArray<string>send_invitationresend_invitationsend_payment_reminderenterreleaserequired
managed_accountobjectrequired
Show child attributes
idintegerrequired
namestring | nullrequired
ownerobjectrequired
Show child attributes
emailstring<email>required
invitationobjectrequired
Show child attributes
expiredbooleanrequired
expires_atstring<date-time>required
deadline_atstring<date-time>required
notice_sent_atstring<date-time> | nullrequired
claimed_atstring<date-time> | nullrequired
reissues_remaininginteger[0, 3]required
created_atstring<date-time>required
updated_atstring<date-time>required
idempotent_replaybooleanrequired
Example
{
  "id": 0,
  "external_ref": "string",
  "source": "dashboard",
  "status": "preparing",
  "permission_set": "operator_v1",
  "allowed_actions": [
    "send_invitation"
  ],
  "managed_account": {
    "id": 0,
    "name": "string"
  },
  "owner": {
    "email": "user@example.com"
  },
  "invitation": {
    "expired": true,
    "expires_at": "2024-01-15T09:30:00Z",
    "deadline_at": "2024-01-15T09:30:00Z",
    "notice_sent_at": "2024-01-15T09:30:00Z",
    "claimed_at": "2024-01-15T09:30:00Z",
    "reissues_remaining": 0
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "idempotent_replay": true
}

DashboardManagedAccountCreateRequest

object
managed_accountobjectrequired
Show child attributes
owner_emailstring<email>required
owner_first_namestring
owner_last_namestring
account_namestringrequired
Example
{
  "managed_account": {
    "owner_email": "user@example.com",
    "owner_first_name": "string",
    "owner_last_name": "string",
    "account_name": "string"
  }
}

PartnerManagedAccountCreateRequest

object
managed_accountobjectrequired
Show child attributes
external_refstringrequired
owner_emailstring<email>required
owner_first_namestring
owner_last_namestring
account_namestringrequired
Example
{
  "managed_account": {
    "external_ref": "string",
    "owner_email": "user@example.com",
    "owner_first_name": "string",
    "owner_last_name": "string",
    "account_name": "string"
  }
}

AccountProvisioningCredential

object
idintegerrequired
namestringrequired
scopesArray<string>provisionmanagerequired
secret_hintstringrequired
expires_atstring<date-time>required
last_used_atstring<date-time> | null
revoked_atstring<date-time> | null
created_atstring<date-time>required
Example
{
  "id": 0,
  "name": "string",
  "scopes": [
    "provision"
  ],
  "secret_hint": "string",
  "expires_at": "2024-01-15T09:30:00Z",
  "last_used_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}

AccountProvisioningCredentialIssued

object
idintegerrequired
namestringrequired
scopesArray<string>provisionmanagerequired
secret_hintstringrequired
expires_atstring<date-time>required
last_used_atstring<date-time> | null
revoked_atstring<date-time> | null
created_atstring<date-time>required
secretstringrequiredwrite only

One-time nspk_live_ credential secret.

Example
{
  "id": 0,
  "name": "string",
  "scopes": [
    "provision"
  ],
  "secret_hint": "string",
  "expires_at": "2024-01-15T09:30:00Z",
  "last_used_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "secret": "string"
}

AccountProvisioningCredentialCreateRequest

object
credentialobjectrequired
Show child attributes
namestringrequired
scopesArray<string>provisionmanagerequired
expires_atstring<date-time>
Example
{
  "credential": {
    "name": "string",
    "scopes": [
      "provision"
    ],
    "expires_at": "2024-01-15T09:30:00Z"
  }
}

AccountManagementCredential

object
idintegerrequired
account_management_grant_idintegerrequired
namestringrequired
permission_setstringoperator_v1required
secret_hintstringrequired
expires_atstring<date-time>required
last_used_atstring<date-time> | null
revoked_atstring<date-time> | null
created_atstring<date-time>required
brandobjectrequired
Show child attributes
idintegerrequired
sidstringrequired
namestringrequired
Example
{
  "id": 0,
  "account_management_grant_id": 0,
  "name": "string",
  "permission_set": "operator_v1",
  "secret_hint": "string",
  "expires_at": "2024-01-15T09:30:00Z",
  "last_used_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "brand": {
    "id": 0,
    "sid": "string",
    "name": "string"
  }
}

AccountManagementCredentialIssued

object
idintegerrequired
account_management_grant_idintegerrequired
namestringrequired
permission_setstringoperator_v1required
secret_hintstringrequired
expires_atstring<date-time>required
last_used_atstring<date-time> | null
revoked_atstring<date-time> | null
created_atstring<date-time>required
brandobjectrequired
Show child attributes
idintegerrequired
sidstringrequired
namestringrequired
secretstringrequiredwrite only

One-time nsmc_live_ credential secret.

Example
{
  "id": 0,
  "account_management_grant_id": 0,
  "name": "string",
  "permission_set": "operator_v1",
  "secret_hint": "string",
  "expires_at": "2024-01-15T09:30:00Z",
  "last_used_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "brand": {
    "id": 0,
    "sid": "string",
    "name": "string"
  },
  "secret": "string"
}

AccountManagementCredentialCreateRequest

object
credentialobjectrequired
Show child attributes
namestringrequired
brand_sidstring

Defaults to the managed Account's default Brand.

expires_atstring<date-time>

Defaults to 90 days and cannot exceed one year.

Example
{
  "credential": {
    "name": "string",
    "brand_sid": "string",
    "expires_at": "2024-01-15T09:30:00Z"
  }
}

ManagedAccountClaimRequest

object
claimobjectrequired
Show child attributes
tokenstringrequiredwrite only
Example
{
  "claim": {
    "token": "string"
  }
}

ManagedAccountClaimCompletionRequest

object
claimobjectrequired
Show child attributes
tokenstringrequiredwrite only
Example
{
  "claim": {
    "token": "string"
  }
}

ManagedAccountClaimInspection

object
managerobjectrequired
Show child attributes
namestring | null
managed_accountobjectrequired
Show child attributes
namestring | null
owner_emailstringrequired

Masked owner address

expires_atstring<date-time>required
authenticationstringrequired
Example
{
  "manager": {
    "name": "string"
  },
  "managed_account": {
    "name": "string"
  },
  "owner_email": "string",
  "expires_at": "2024-01-15T09:30:00Z",
  "authentication": "login_required"
}

ManagedAccountClaimCompletion

object
claimedbooleanrequired
statusstringpayment_requiredactivemanager_disabledrequired
managed_accountobjectrequired
Show child attributes
idintegerrequired
namestring | nullrequired
Example
{
  "claimed": true,
  "status": "payment_required",
  "managed_account": {
    "id": 0,
    "name": "string"
  }
}

Account

object
idinteger
namestring | null
avatarstring | null

Signed blob ID

bannerstring | null

Signed blob ID

commercial_tierstringunsubscribedfreeproultraenterprise
safe_mode_enabledboolean
accessAccountAccess
Show child attributes
sourcestringownermembershipplatform_admindelegatedmanagement_credentialapi_keyshopifyrequired
delegatedbooleanrequired
manager_account_idinteger
manager_account_namestring | null
management_grant_idinteger
permission_setstringoperator_v1
credential_typestringmanagement
billingobject

Present for direct access and omitted from delegated account-list projections.

Show child attributes
access_policystring | nullfree_allowedpaid_requiredrequired
plan_namestring | null
planPlan | null
spend_cap_monthly_centsinteger | null>= 0
compedboolean
overageobject
entitlementsBillingEntitlements
Show child attributes
agent_inboxAgentInboxEntitlementrequired
Show child attributes
enabledbooleanrequired
max_inboxesinteger | null>= 0required

Account-wide exact-inbox capacity. Null means contract-defined unlimited capacity.

inbound_messages_includedinteger | null>= 0required
inbound_messages_meteredbooleanrequired
inbound_message_overage_rate_centsstringrequired
max_inbound_domainsinteger | null>= 0required
max_apex_domainsinteger | null>= 0required
apex_mxbooleanrequired
legacy_forwardingbooleanrequired
catch_allbooleanrequired
retention_daysinteger | null>= 0required
advanced_queue_controlsbooleanrequired
resourcesobject
Show child attributes
emailAccountResourceUsage
Show child attributes
usedintegerrequired
allowanceinteger | nullrequired
remaininginteger | nullrequired
overage_ratenumberrequired
modestringbudgetmonthlyunlimitedrequired
budgetinteger | nullrequired
budget_usedintegerrequired
smsAccountResourceUsage
Show child attributes
usedintegerrequired
allowanceinteger | nullrequired
remaininginteger | nullrequired
overage_ratenumberrequired
modestringbudgetmonthlyunlimitedrequired
budgetinteger | nullrequired
budget_usedintegerrequired
aiAccountResourceUsage
Show child attributes
usedintegerrequired
allowanceinteger | nullrequired
remaininginteger | nullrequired
overage_ratenumberrequired
modestringbudgetmonthlyunlimitedrequired
budgetinteger | nullrequired
budget_usedintegerrequired
fundingobjectrequired
provider_routeobjectrequired
brandsobjectrequired

Per-account brand-count headroom. Usage for email, SMS, and AI remains pooled at the account level; only brand count is capped here. A limit of 0 with unlimited=true means unlimited brands.

Show child attributes
usedinteger
limitinteger

Raw plan max_brands value. 0 means unlimited when unlimited is true.

remaininginteger | null

Null when unlimited is true.

unlimitedboolean
can_createboolean

True when plan headroom allows creating another brand.

lifetimeobject
Show child attributes
email_sentinteger
sms_sentinteger
ai_usedinteger
teamobject

Present for direct access and omitted from delegated account-list projections.

Show child attributes
seat_limitinteger
seat_countinteger
member_countinteger
invite_countinteger
current_rolestring | null
can_manage_teamboolean
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "name": "string",
  "avatar": "string",
  "banner": "string",
  "commercial_tier": "unsubscribed",
  "safe_mode_enabled": true,
  "access": {
    "source": "owner",
    "delegated": true,
    "manager_account_id": 0,
    "manager_account_name": "string",
    "management_grant_id": 0,
    "permission_set": "operator_v1",
    "credential_type": "management"
  },
  "billing": {
    "access_policy": "free_allowed",
    "plan_name": "string",
    "plan": {
      "id": 0,
      "name": "string",
      "active": true,
      "probation_recipient_cap_24h": 0,
      "standard_recipient_cap_24h": 0,
      "trusted_recipient_cap_24h": 0,
      "entitlements": {
        "agent_inbox": {
          "enabled": true,
          "max_inboxes": 0,
          "inbound_messages_included": 0,
          "inbound_messages_metered": true,
          "inbound_message_overage_rate_cents": "string",
          "max_inbound_domains": 0,
          "max_apex_domains": 0,
          "apex_mx": true,
          "legacy_forwarding": true,
          "catch_all": true,
          "retention_days": 0,
          "advanced_queue_controls": true
        }
      }
    },
    "spend_cap_monthly_cents": 0,
    "comped": true,
    "overage": {},
    "entitlements": {
      "agent_inbox": {
        "enabled": true,
        "max_inboxes": 0,
        "inbound_messages_included": 0,
        "inbound_messages_metered": true,
        "inbound_message_overage_rate_cents": "string",
        "max_inbound_domains": 0,
        "max_apex_domains": 0,
        "apex_mx": true,
        "legacy_forwarding": true,
        "catch_all": true,
        "retention_days": 0,
        "advanced_queue_controls": true
      }
    },
    "resources": {
      "email": {
        "used": 0,
        "allowance": 0,
        "remaining": 0,
        "overage_rate": 0,
        "mode": "budget",
        "budget": 0,
        "budget_used": 0
      },
      "sms": {
        "used": 0,
        "allowance": 0,
        "remaining": 0,
        "overage_rate": 0,
        "mode": "budget",
        "budget": 0,
        "budget_used": 0
      },
      "ai": {
        "used": 0,
        "allowance": 0,
        "remaining": 0,
        "overage_rate": 0,
        "mode": "budget",
        "budget": 0,
        "budget_used": 0
      }
    },
    "funding": {},
    "provider_route": {},
    "brands": {
      "used": 0,
      "limit": 0,
      "remaining": 0,
      "unlimited": true,
      "can_create": true
    },
    "lifetime": {
      "email_sent": 0,
      "sms_sent": 0,
      "ai_used": 0
    }
  },
  "team": {
    "seat_limit": 0,
    "seat_count": 0,
    "member_count": 0,
    "invite_count": 0,
    "current_role": "string",
    "can_manage_team": true
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

SendingPause

object

What the owner of a suspended account is told. A deliverability pause names the metric and the fix (reason, what_to_do). Any other suspension is opaque and carries no reason. Recovery actions reach the existing support channel.

sending_pausedbooleantruerequired
reasonstringcritical_bounce_ratecritical_complaint_rate

Present only for an explained deliverability pause.

occurred_atstring<date-time>required
headlinestringrequired
detailstringrequired
what_to_doArray<string>

Present only for an explained deliverability pause.

request_reviewstringrequired

The instruction an agent relays to the owner.

recovery_actionsArray<object>required
Show child attributes
typestringverify_listrequest_reviewcontact_supportrequired
labelstringrequired
urlstringrequired

App link or support mailto.

Example
{
  "sending_paused": true,
  "reason": "critical_bounce_rate",
  "occurred_at": "2024-01-15T09:30:00Z",
  "headline": "string",
  "detail": "string",
  "what_to_do": [
    "string"
  ],
  "request_review": "string",
  "recovery_actions": [
    {
      "type": "verify_list",
      "label": "string",
      "url": "string"
    }
  ]
}

AccountResourceUsage

object
usedintegerrequired
allowanceinteger | nullrequired
remaininginteger | nullrequired
overage_ratenumberrequired
modestringbudgetmonthlyunlimitedrequired
budgetinteger | nullrequired
budget_usedintegerrequired
Example
{
  "used": 0,
  "allowance": 0,
  "remaining": 0,
  "overage_rate": 0,
  "mode": "budget",
  "budget": 0,
  "budget_used": 0
}

AccountAccess

object
sourcestringownermembershipplatform_admindelegatedmanagement_credentialapi_keyshopifyrequired
delegatedbooleanrequired
manager_account_idinteger
manager_account_namestring | null
management_grant_idinteger
permission_setstringoperator_v1
credential_typestringmanagement
Example
{
  "source": "owner",
  "delegated": true,
  "manager_account_id": 0,
  "manager_account_name": "string",
  "management_grant_id": 0,
  "permission_set": "operator_v1",
  "credential_type": "management"
}

AccountManagementGrant

object
idintegerrequired
statusstringpendingactiverevokedreleasedrequired
permission_setstringoperator_v1required
manager_accountobjectrequired
Show child attributes
idintegerrequired
namestring | null
requested_atstring<date-time>required
activated_atstring<date-time> | null
revoked_atstring<date-time> | null
released_atstring<date-time> | null
Example
{
  "id": 0,
  "status": "pending",
  "permission_set": "operator_v1",
  "manager_account": {
    "id": 0,
    "name": "string"
  },
  "requested_at": "2024-01-15T09:30:00Z",
  "activated_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "released_at": "2024-01-15T09:30:00Z"
}

AccountManagementGrantCommand

object
management_grant_idintegerrequired

Exact grant returned by the show endpoint; prevents a stale command from targeting a replacement grant.

Example
{
  "management_grant_id": 0
}

AccountTeam

object
accountAccount
Show child attributes
idinteger
namestring | null
avatarstring | null

Signed blob ID

bannerstring | null

Signed blob ID

commercial_tierstringunsubscribedfreeproultraenterprise
safe_mode_enabledboolean
accessAccountAccess
Show child attributes
sourcestringownermembershipplatform_admindelegatedmanagement_credentialapi_keyshopifyrequired
delegatedbooleanrequired
manager_account_idinteger
manager_account_namestring | null
management_grant_idinteger
permission_setstringoperator_v1
credential_typestringmanagement
billingobject

Present for direct access and omitted from delegated account-list projections.

Show child attributes
access_policystring | nullfree_allowedpaid_requiredrequired
plan_namestring | null
planPlan | null
spend_cap_monthly_centsinteger | null>= 0
compedboolean
overageobject
entitlementsBillingEntitlements
Show child attributes
agent_inboxAgentInboxEntitlementrequired
Show child attributes
enabledbooleanrequired
max_inboxesinteger | null>= 0required

Account-wide exact-inbox capacity. Null means contract-defined unlimited capacity.

inbound_messages_includedinteger | null>= 0required
inbound_messages_meteredbooleanrequired
inbound_message_overage_rate_centsstringrequired
max_inbound_domainsinteger | null>= 0required
max_apex_domainsinteger | null>= 0required
apex_mxbooleanrequired
legacy_forwardingbooleanrequired
catch_allbooleanrequired
retention_daysinteger | null>= 0required
advanced_queue_controlsbooleanrequired
resourcesobject
Show child attributes
emailAccountResourceUsage
Show child attributes
usedintegerrequired
allowanceinteger | nullrequired
remaininginteger | nullrequired
overage_ratenumberrequired
modestringbudgetmonthlyunlimitedrequired
budgetinteger | nullrequired
budget_usedintegerrequired
smsAccountResourceUsage
Show child attributes
usedintegerrequired
allowanceinteger | nullrequired
remaininginteger | nullrequired
overage_ratenumberrequired
modestringbudgetmonthlyunlimitedrequired
budgetinteger | nullrequired
budget_usedintegerrequired
aiAccountResourceUsage
Show child attributes
usedintegerrequired
allowanceinteger | nullrequired
remaininginteger | nullrequired
overage_ratenumberrequired
modestringbudgetmonthlyunlimitedrequired
budgetinteger | nullrequired
budget_usedintegerrequired
fundingobjectrequired
provider_routeobjectrequired
brandsobjectrequired

Per-account brand-count headroom. Usage for email, SMS, and AI remains pooled at the account level; only brand count is capped here. A limit of 0 with unlimited=true means unlimited brands.

Show child attributes
usedinteger
limitinteger

Raw plan max_brands value. 0 means unlimited when unlimited is true.

remaininginteger | null

Null when unlimited is true.

unlimitedboolean
can_createboolean

True when plan headroom allows creating another brand.

lifetimeobject
Show child attributes
email_sentinteger
sms_sentinteger
ai_usedinteger
teamobject

Present for direct access and omitted from delegated account-list projections.

Show child attributes
seat_limitinteger
seat_countinteger
member_countinteger
invite_countinteger
current_rolestring | null
can_manage_teamboolean
created_atstring<date-time>
updated_atstring<date-time>
membershipsArray<AccountMembership>
Show child attributes
idinteger
rolestringmemberadminowner
user_idinteger
emailstring<email>
namestring | null
created_atstring<date-time>
updated_atstring<date-time>
invitesArray<AccountInvite>
Show child attributes
idinteger
account_idinteger
emailstring<email>
rolestringmemberadmin
tokenstring
statusstringpendingacceptedrevokedexpired
accepted_atstring<date-time> | null
revoked_atstring<date-time> | null
expires_atstring<date-time> | null
created_atstring<date-time>
updated_atstring<date-time>
accessible_accountsArray<Account>
Show child attributes
idinteger
namestring | null
avatarstring | null

Signed blob ID

bannerstring | null

Signed blob ID

commercial_tierstringunsubscribedfreeproultraenterprise
safe_mode_enabledboolean
accessAccountAccess
Show child attributes
sourcestringownermembershipplatform_admindelegatedmanagement_credentialapi_keyshopifyrequired
delegatedbooleanrequired
manager_account_idinteger
manager_account_namestring | null
management_grant_idinteger
permission_setstringoperator_v1
credential_typestringmanagement
billingobject

Present for direct access and omitted from delegated account-list projections.

Show child attributes
access_policystring | nullfree_allowedpaid_requiredrequired
plan_namestring | null
planPlan | null
spend_cap_monthly_centsinteger | null>= 0
compedboolean
overageobject
entitlementsBillingEntitlements
Show child attributes
agent_inboxAgentInboxEntitlementrequired
Show child attributes
enabledbooleanrequired
max_inboxesinteger | null>= 0required

Account-wide exact-inbox capacity. Null means contract-defined unlimited capacity.

inbound_messages_includedinteger | null>= 0required
inbound_messages_meteredbooleanrequired
inbound_message_overage_rate_centsstringrequired
max_inbound_domainsinteger | null>= 0required
max_apex_domainsinteger | null>= 0required
apex_mxbooleanrequired
legacy_forwardingbooleanrequired
catch_allbooleanrequired
retention_daysinteger | null>= 0required
advanced_queue_controlsbooleanrequired
resourcesobject
Show child attributes
emailAccountResourceUsage
Show child attributes
usedintegerrequired
allowanceinteger | nullrequired
remaininginteger | nullrequired
overage_ratenumberrequired
modestringbudgetmonthlyunlimitedrequired
budgetinteger | nullrequired
budget_usedintegerrequired
smsAccountResourceUsage
Show child attributes
usedintegerrequired
allowanceinteger | nullrequired
remaininginteger | nullrequired
overage_ratenumberrequired
modestringbudgetmonthlyunlimitedrequired
budgetinteger | nullrequired
budget_usedintegerrequired
aiAccountResourceUsage
Show child attributes
usedintegerrequired
allowanceinteger | nullrequired
remaininginteger | nullrequired
overage_ratenumberrequired
modestringbudgetmonthlyunlimitedrequired
budgetinteger | nullrequired
budget_usedintegerrequired
fundingobjectrequired
provider_routeobjectrequired
brandsobjectrequired

Per-account brand-count headroom. Usage for email, SMS, and AI remains pooled at the account level; only brand count is capped here. A limit of 0 with unlimited=true means unlimited brands.

Show child attributes
usedinteger
limitinteger

Raw plan max_brands value. 0 means unlimited when unlimited is true.

remaininginteger | null

Null when unlimited is true.

unlimitedboolean
can_createboolean

True when plan headroom allows creating another brand.

lifetimeobject
Show child attributes
email_sentinteger
sms_sentinteger
ai_usedinteger
teamobject

Present for direct access and omitted from delegated account-list projections.

Show child attributes
seat_limitinteger
seat_countinteger
member_countinteger
invite_countinteger
current_rolestring | null
can_manage_teamboolean
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "account": {
    "id": 0,
    "name": "string",
    "avatar": "string",
    "banner": "string",
    "commercial_tier": "unsubscribed",
    "safe_mode_enabled": true,
    "access": {
      "source": "owner",
      "delegated": true,
      "manager_account_id": 0,
      "manager_account_name": "string",
      "management_grant_id": 0,
      "permission_set": "operator_v1",
      "credential_type": "management"
    },
    "billing": {
      "access_policy": "free_allowed",
      "plan_name": "string",
      "plan": {
        "id": 0,
        "name": "string",
        "active": true,
        "probation_recipient_cap_24h": 0,
        "standard_recipient_cap_24h": 0,
        "trusted_recipient_cap_24h": 0,
        "entitlements": {
          "agent_inbox": {
            "enabled": true,
            "max_inboxes": 0,
            "inbound_messages_included": 0,
            "inbound_messages_metered": true,
            "inbound_message_overage_rate_cents": "string",
            "max_inbound_domains": 0,
            "max_apex_domains": 0,
            "apex_mx": true,
            "legacy_forwarding": true,
            "catch_all": true,
            "retention_days": 0,
            "advanced_queue_controls": true
          }
        }
      },
      "spend_cap_monthly_cents": 0,
      "comped": true,
      "overage": {},
      "entitlements": {
        "agent_inbox": {
          "enabled": true,
          "max_inboxes": 0,
          "inbound_messages_included": 0,
          "inbound_messages_metered": true,
          "inbound_message_overage_rate_cents": "string",
          "max_inbound_domains": 0,
          "max_apex_domains": 0,
          "apex_mx": true,
          "legacy_forwarding": true,
          "catch_all": true,
          "retention_days": 0,
          "advanced_queue_controls": true
        }
      },
      "resources": {
        "email": {
          "used": 0,
          "allowance": 0,
          "remaining": 0,
          "overage_rate": 0,
          "mode": "budget",
          "budget": 0,
          "budget_used": 0
        },
        "sms": {
          "used": 0,
          "allowance": 0,
          "remaining": 0,
          "overage_rate": 0,
          "mode": "budget",
          "budget": 0,
          "budget_used": 0
        },
        "ai": {
          "used": 0,
          "allowance": 0,
          "remaining": 0,
          "overage_rate": 0,
          "mode": "budget",
          "budget": 0,
          "budget_used": 0
        }
      },
      "funding": {},
      "provider_route": {},
      "brands": {
        "used": 0,
        "limit": 0,
        "remaining": 0,
        "unlimited": true,
        "can_create": true
      },
      "lifetime": {
        "email_sent": 0,
        "sms_sent": 0,
        "ai_used": 0
      }
    },
    "team": {
      "seat_limit": 0,
      "seat_count": 0,
      "member_count": 0,
      "invite_count": 0,
      "current_role": "string",
      "can_manage_team": true
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "memberships": [
    {
      "id": 0,
      "role": "member",
      "user_id": 0,
      "email": "user@example.com",
      "name": "string",
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ],
  "invites": [
    {
      "id": 0,
      "account_id": 0,
      "email": "user@example.com",
      "role": "member",
      "token": "string",
      "status": "pending",
      "accepted_at": "2024-01-15T09:30:00Z",
      "revoked_at": "2024-01-15T09:30:00Z",
      "expires_at": "2024-01-15T09:30:00Z",
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ],
  "accessible_accounts": [
    {
      "id": 0,
      "name": "string",
      "avatar": "string",
      "banner": "string",
      "commercial_tier": "unsubscribed",
      "safe_mode_enabled": true,
      "access": {
        "source": "owner",
        "delegated": true,
        "manager_account_id": 0,
        "manager_account_name": "string",
        "management_grant_id": 0,
        "permission_set": "operator_v1",
        "credential_type": "management"
      },
      "billing": {
        "access_policy": "free_allowed",
        "plan_name": "string",
        "plan": {
          "id": 0,
          "name": "string",
          "active": true,
          "probation_recipient_cap_24h": 0,
          "standard_recipient_cap_24h": 0,
          "trusted_recipient_cap_24h": 0,
          "entitlements": {
            "agent_inbox": {
              "enabled": true,
              "max_inboxes": 0,
              "inbound_messages_included": 0,
              "inbound_messages_metered": true,
              "inbound_message_overage_rate_cents": "string",
              "max_inbound_domains": 0,
              "max_apex_domains": 0,
              "apex_mx": true,
              "legacy_forwarding": true,
              "catch_all": true,
              "retention_days": 0,
              "advanced_queue_controls": true
            }
          }
        },
        "spend_cap_monthly_cents": 0,
        "comped": true,
        "overage": {},
        "entitlements": {
          "agent_inbox": {
            "enabled": true,
            "max_inboxes": 0,
            "inbound_messages_included": 0,
            "inbound_messages_metered": true,
            "inbound_message_overage_rate_cents": "string",
            "max_inbound_domains": 0,
            "max_apex_domains": 0,
            "apex_mx": true,
            "legacy_forwarding": true,
            "catch_all": true,
            "retention_days": 0,
            "advanced_queue_controls": true
          }
        },
        "resources": {
          "email": {
            "used": 0,
            "allowance": 0,
            "remaining": 0,
            "overage_rate": 0,
            "mode": "budget",
            "budget": 0,
            "budget_used": 0
          },
          "sms": {
            "used": 0,
            "allowance": 0,
            "remaining": 0,
            "overage_rate": 0,
            "mode": "budget",
            "budget": 0,
            "budget_used": 0
          },
          "ai": {
            "used": 0,
            "allowance": 0,
            "remaining": 0,
            "overage_rate": 0,
            "mode": "budget",
            "budget": 0,
            "budget_used": 0
          }
        },
        "funding": {},
        "provider_route": {},
        "brands": {
          "used": 0,
          "limit": 0,
          "remaining": 0,
          "unlimited": true,
          "can_create": true
        },
        "lifetime": {
          "email_sent": 0,
          "sms_sent": 0,
          "ai_used": 0
        }
      },
      "team": {
        "seat_limit": 0,
        "seat_count": 0,
        "member_count": 0,
        "invite_count": 0,
        "current_role": "string",
        "can_manage_team": true
      },
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}

AccountMembership

object
idinteger
rolestringmemberadminowner
user_idinteger
emailstring<email>
namestring | null
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "role": "member",
  "user_id": 0,
  "email": "user@example.com",
  "name": "string",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

AccountInvite

object
idinteger
account_idinteger
emailstring<email>
rolestringmemberadmin
tokenstring
statusstringpendingacceptedrevokedexpired
accepted_atstring<date-time> | null
revoked_atstring<date-time> | null
expires_atstring<date-time> | null
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "account_id": 0,
  "email": "user@example.com",
  "role": "member",
  "token": "string",
  "status": "pending",
  "accepted_at": "2024-01-15T09:30:00Z",
  "revoked_at": "2024-01-15T09:30:00Z",
  "expires_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

Subscription

object
idinteger
plan_idinteger
plan_namestring | null
billing_providerstring | nullshopifystripestripe_projectsvercelaws
source_billing_providerstring | nullshopifystripestripe_projectsvercelaws
billing_migration_requiredboolean
manage_urlstring<uri> | null
spend_cap_monthly_centsinteger | null>= 0

Merchant-selected monthly cap for metered usage charges.

shopify_usage_meteredboolean

Whether the active Shopify plan has at least one configured usage meter.

statusstringpendingactiveinactivecanceledfree_tier
intervalstringmonthyearweekday
currencystring
subtotal_centsinteger
tax_centsinteger
total_centsinteger
base_price_centsinteger
discount_centsinteger

Per-period Stripe discount in cents (0 when none).

next_payment_centsinteger

Amount billed next period

discount_end_atstring<date-time> | null

When the discount stops (null for forever/once or no discount).

activatedboolean
entitlementsBillingEntitlements
Show child attributes
agent_inboxAgentInboxEntitlementrequired
Show child attributes
enabledbooleanrequired
max_inboxesinteger | null>= 0required

Account-wide exact-inbox capacity. Null means contract-defined unlimited capacity.

inbound_messages_includedinteger | null>= 0required
inbound_messages_meteredbooleanrequired
inbound_message_overage_rate_centsstringrequired
max_inbound_domainsinteger | null>= 0required
max_apex_domainsinteger | null>= 0required
apex_mxbooleanrequired
legacy_forwardingbooleanrequired
catch_allbooleanrequired
retention_daysinteger | null>= 0required
advanced_queue_controlsbooleanrequired
Example
{
  "id": 0,
  "plan_id": 0,
  "plan_name": "string",
  "billing_provider": "shopify",
  "source_billing_provider": "shopify",
  "billing_migration_required": true,
  "manage_url": "https://example.com",
  "spend_cap_monthly_cents": 0,
  "shopify_usage_metered": true,
  "status": "pending",
  "interval": "month",
  "currency": "string",
  "subtotal_cents": 0,
  "tax_cents": 0,
  "total_cents": 0,
  "base_price_cents": 0,
  "discount_cents": 0,
  "next_payment_cents": 0,
  "discount_end_at": "2024-01-15T09:30:00Z",
  "activated": true,
  "entitlements": {
    "agent_inbox": {
      "enabled": true,
      "max_inboxes": 0,
      "inbound_messages_included": 0,
      "inbound_messages_metered": true,
      "inbound_message_overage_rate_cents": "string",
      "max_inbound_domains": 0,
      "max_apex_domains": 0,
      "apex_mx": true,
      "legacy_forwarding": true,
      "catch_all": true,
      "retention_days": 0,
      "advanced_queue_controls": true
    }
  }
}

BillingEntitlements

object
agent_inboxAgentInboxEntitlementrequired
Show child attributes
enabledbooleanrequired
max_inboxesinteger | null>= 0required

Account-wide exact-inbox capacity. Null means contract-defined unlimited capacity.

inbound_messages_includedinteger | null>= 0required
inbound_messages_meteredbooleanrequired
inbound_message_overage_rate_centsstringrequired
max_inbound_domainsinteger | null>= 0required
max_apex_domainsinteger | null>= 0required
apex_mxbooleanrequired
legacy_forwardingbooleanrequired
catch_allbooleanrequired
retention_daysinteger | null>= 0required
advanced_queue_controlsbooleanrequired
Example
{
  "agent_inbox": {
    "enabled": true,
    "max_inboxes": 0,
    "inbound_messages_included": 0,
    "inbound_messages_metered": true,
    "inbound_message_overage_rate_cents": "string",
    "max_inbound_domains": 0,
    "max_apex_domains": 0,
    "apex_mx": true,
    "legacy_forwarding": true,
    "catch_all": true,
    "retention_days": 0,
    "advanced_queue_controls": true
  }
}

AgentInboxEntitlement

object
enabledbooleanrequired
max_inboxesinteger | null>= 0required

Account-wide exact-inbox capacity. Null means contract-defined unlimited capacity.

inbound_messages_includedinteger | null>= 0required
inbound_messages_meteredbooleanrequired
inbound_message_overage_rate_centsstringrequired
max_inbound_domainsinteger | null>= 0required
max_apex_domainsinteger | null>= 0required
apex_mxbooleanrequired
legacy_forwardingbooleanrequired
catch_allbooleanrequired
retention_daysinteger | null>= 0required
advanced_queue_controlsbooleanrequired
Example
{
  "enabled": true,
  "max_inboxes": 0,
  "inbound_messages_included": 0,
  "inbound_messages_metered": true,
  "inbound_message_overage_rate_cents": "string",
  "max_inbound_domains": 0,
  "max_apex_domains": 0,
  "apex_mx": true,
  "legacy_forwarding": true,
  "catch_all": true,
  "retention_days": 0,
  "advanced_queue_controls": true
}

SubscriptionCreateRequest

object
plan_idintegerrequired
stripe_tokenstring | null

Stripe card token for paid-plan creation.

coupon_codestring | null

Customer-entered Stripe promotion code or coupon ID.

Example
{
  "plan_id": 0,
  "stripe_token": "string",
  "coupon_code": "string"
}

FundingPurchaseCreateRequest

object
amount_centsinteger>= 1required

Integer service value in minor currency units.

currencystring
instrumentstringstripe_checkoutshopify_one_time

Optional hosted funding instrument. Omit to use the account default.

paid_action_intent_idstring | null

Optional opaque continuation bound to this funding purchase.

Example
{
  "amount_cents": 1,
  "currency": "string",
  "instrument": "stripe_checkout",
  "paid_action_intent_id": "string"
}

FundingInstrument

object
instrumentstringstripe_checkoutshopify_one_timerequired
providerstringstripeshopifyrequired
modestringhosted_approvalrequired
availablebooleanrequired
reasonstring | null
Example
{
  "instrument": "stripe_checkout",
  "provider": "stripe",
  "mode": "hosted_approval",
  "available": true,
  "reason": "string"
}

FundingUrlApproval

object
kindstringurlrequired
providerstringstripeshopifyrequired
urlstring<uri>required
targetstringselftoprequired
Example
{
  "kind": "url",
  "provider": "stripe",
  "url": "https://example.com",
  "target": "self"
}

FundingChallengeApproval

object
kindstringchallengerequired
instrumentstringrequired
protocolstringrequired
challengestringrequired
expires_atstring<date-time> | null
Example
{
  "kind": "challenge",
  "instrument": "string",
  "protocol": "string",
  "challenge": "string",
  "expires_at": "2024-01-15T09:30:00Z"
}

FundingApproval

object
One of
kindstringurlrequired
providerstringstripeshopifyrequired
urlstring<uri>required
targetstringselftoprequired
kindstringchallengerequired
instrumentstringrequired
protocolstringrequired
challengestringrequired
expires_atstring<date-time> | null
Example
{
  "kind": "url",
  "provider": "stripe",
  "url": "https://example.com",
  "target": "self"
}

FundingPurchase

object
idintegerrequired
paid_action_intent_idstring | null
providerstringstripeshopifyrequired
instrumentstringstripe_checkoutshopify_one_timestripe_off_sessionrequired
statusstringrequestedpendingcheckout_createdcreditedfailedexpiredpartially_reversedreversedrequired
currencystringrequired
requested_centsinteger>= 1required
requested_displaystring
checkout_urlstring<uri> | null
approvalFundingUrlApproval | FundingChallengeApproval | null
expires_atstring<date-time> | null
credited_centsinteger>= 0required
reversed_centsinteger>= 0required
created_atstring<date-time>required
updated_atstring<date-time>required
Example
{
  "id": 0,
  "paid_action_intent_id": "string",
  "provider": "stripe",
  "instrument": "stripe_checkout",
  "status": "requested",
  "currency": "string",
  "requested_cents": 1,
  "requested_display": "string",
  "checkout_url": "https://example.com",
  "approval": {
    "kind": "url",
    "provider": "stripe",
    "url": "https://example.com",
    "target": "self"
  },
  "expires_at": "2024-01-15T09:30:00Z",
  "credited_cents": 0,
  "reversed_cents": 0,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

FundingPurchaseCapability

object
availablebooleanrequired
statestringrequired
reasonstring | null
default_instrumentstring | nullstripe_checkoutshopify_one_time
instrumentsArray<FundingInstrument>required
Show child attributes
instrumentstringstripe_checkoutshopify_one_timerequired
providerstringstripeshopifyrequired
modestringhosted_approvalrequired
availablebooleanrequired
reasonstring | null
currencystringrequired
minimum_centsinteger | null
maximum_centsinteger | null
preset_centsArray<integer>required
Example
{
  "available": true,
  "state": "string",
  "reason": "string",
  "default_instrument": "stripe_checkout",
  "instruments": [
    {
      "instrument": "stripe_checkout",
      "provider": "stripe",
      "mode": "hosted_approval",
      "available": true,
      "reason": "string"
    }
  ],
  "currency": "string",
  "minimum_cents": 0,
  "maximum_cents": 0,
  "preset_cents": [
    0
  ]
}

FundingStatus

object
statestringrequired
applies_tostringprepaid_featuresrequired
subscription_gatebooleanrequired
currencystringrequired
available_centsintegerrequired
reserved_centsintegerrequired
deficit_centsintegerrequired
purchaseFundingPurchaseCapabilityrequired
Show child attributes
availablebooleanrequired
statestringrequired
reasonstring | null
default_instrumentstring | nullstripe_checkoutshopify_one_time
instrumentsArray<FundingInstrument>required
Show child attributes
instrumentstringstripe_checkoutshopify_one_timerequired
providerstringstripeshopifyrequired
modestringhosted_approvalrequired
availablebooleanrequired
reasonstring | null
currencystringrequired
minimum_centsinteger | null
maximum_centsinteger | null
preset_centsArray<integer>required
pending_purchaseFundingPurchase | null
Example
{
  "state": "string",
  "applies_to": "prepaid_features",
  "subscription_gate": true,
  "currency": "string",
  "available_cents": 0,
  "reserved_cents": 0,
  "deficit_cents": 0,
  "purchase": {
    "available": true,
    "state": "string",
    "reason": "string",
    "default_instrument": "stripe_checkout",
    "instruments": [
      {
        "instrument": "stripe_checkout",
        "provider": "stripe",
        "mode": "hosted_approval",
        "available": true,
        "reason": "string"
      }
    ],
    "currency": "string",
    "minimum_cents": 0,
    "maximum_cents": 0,
    "preset_cents": [
      0
    ]
  },
  "pending_purchase": {
    "id": 0,
    "paid_action_intent_id": "string",
    "provider": "stripe",
    "instrument": "stripe_checkout",
    "status": "requested",
    "currency": "string",
    "requested_cents": 1,
    "requested_display": "string",
    "checkout_url": "https://example.com",
    "approval": {
      "kind": "url",
      "provider": "stripe",
      "url": "https://example.com",
      "target": "self"
    },
    "expires_at": "2024-01-15T09:30:00Z",
    "credited_cents": 0,
    "reversed_cents": 0,
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  }
}

FundingPurchaseResponse

object
purchaseFundingPurchaserequired
Show child attributes
idintegerrequired
paid_action_intent_idstring | null
providerstringstripeshopifyrequired
instrumentstringstripe_checkoutshopify_one_timestripe_off_sessionrequired
statusstringrequestedpendingcheckout_createdcreditedfailedexpiredpartially_reversedreversedrequired
currencystringrequired
requested_centsinteger>= 1required
requested_displaystring
checkout_urlstring<uri> | null
approvalFundingUrlApproval | FundingChallengeApproval | null
expires_atstring<date-time> | null
credited_centsinteger>= 0required
reversed_centsinteger>= 0required
created_atstring<date-time>required
updated_atstring<date-time>required
fundingFundingStatusrequired
Show child attributes
statestringrequired
applies_tostringprepaid_featuresrequired
subscription_gatebooleanrequired
currencystringrequired
available_centsintegerrequired
reserved_centsintegerrequired
deficit_centsintegerrequired
purchaseFundingPurchaseCapabilityrequired
Show child attributes
availablebooleanrequired
statestringrequired
reasonstring | null
default_instrumentstring | nullstripe_checkoutshopify_one_time
instrumentsArray<FundingInstrument>required
Show child attributes
instrumentstringstripe_checkoutshopify_one_timerequired
providerstringstripeshopifyrequired
modestringhosted_approvalrequired
availablebooleanrequired
reasonstring | null
currencystringrequired
minimum_centsinteger | null
maximum_centsinteger | null
preset_centsArray<integer>required
pending_purchaseFundingPurchase | null
Example
{
  "purchase": {
    "id": 0,
    "paid_action_intent_id": "string",
    "provider": "stripe",
    "instrument": "stripe_checkout",
    "status": "requested",
    "currency": "string",
    "requested_cents": 1,
    "requested_display": "string",
    "checkout_url": "https://example.com",
    "approval": {
      "kind": "url",
      "provider": "stripe",
      "url": "https://example.com",
      "target": "self"
    },
    "expires_at": "2024-01-15T09:30:00Z",
    "credited_cents": 0,
    "reversed_cents": 0,
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "funding": {
    "state": "string",
    "applies_to": "prepaid_features",
    "subscription_gate": true,
    "currency": "string",
    "available_cents": 0,
    "reserved_cents": 0,
    "deficit_cents": 0,
    "purchase": {
      "available": true,
      "state": "string",
      "reason": "string",
      "default_instrument": "stripe_checkout",
      "instruments": [
        {
          "instrument": "stripe_checkout",
          "provider": "stripe",
          "mode": "hosted_approval",
          "available": true,
          "reason": "string"
        }
      ],
      "currency": "string",
      "minimum_cents": 0,
      "maximum_cents": 0,
      "preset_cents": [
        0
      ]
    },
    "pending_purchase": {
      "id": 0,
      "paid_action_intent_id": "string",
      "provider": "stripe",
      "instrument": "stripe_checkout",
      "status": "requested",
      "currency": "string",
      "requested_cents": 1,
      "requested_display": "string",
      "checkout_url": "https://example.com",
      "approval": {
        "kind": "url",
        "provider": "stripe",
        "url": "https://example.com",
        "target": "self"
      },
      "expires_at": "2024-01-15T09:30:00Z",
      "credited_cents": 0,
      "reversed_cents": 0,
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  }
}

SubscriptionChangeRequest

object
plan_idintegerrequired
coupon_codestring | null

Customer-entered Stripe promotion code or coupon ID.

Example
{
  "plan_id": 0,
  "coupon_code": "string"
}

SubscriptionCouponPreviewRequest

object
plan_idintegerrequired
coupon_codestringrequired

Customer-entered Stripe promotion code or coupon ID.

Example
{
  "plan_id": 0,
  "coupon_code": "string"
}

SubscriptionCouponPreview

object
codestringrequired
discount_labelstringrequired
discount_centsintegerrequired
subtotal_centsintegerrequired
tax_centsintegerrequired
total_centsintegerrequired
total_after_discount_centsintegerrequired
currencystringrequired
Example
{
  "code": "string",
  "discount_label": "string",
  "discount_cents": 0,
  "subtotal_cents": 0,
  "tax_cents": 0,
  "total_cents": 0,
  "total_after_discount_cents": 0,
  "currency": "string"
}

OAuthPopupAccount

object
idintegerrequired
namestringrequired
accessAccountAccess
Show child attributes
sourcestringownermembershipplatform_admindelegatedmanagement_credentialapi_keyshopifyrequired
delegatedbooleanrequired
manager_account_idinteger
manager_account_namestring | null
management_grant_idinteger
permission_setstringoperator_v1
credential_typestringmanagement
can_manageboolean
needs_subscribebooleanrequired
Example
{
  "id": 0,
  "name": "string",
  "access": {
    "source": "owner",
    "delegated": true,
    "manager_account_id": 0,
    "manager_account_name": "string",
    "management_grant_id": 0,
    "permission_set": "operator_v1",
    "credential_type": "management"
  },
  "can_manage": true,
  "needs_subscribe": true
}

OAuthPopupPlan

object
idintegerrequired
namestringrequired
slugstringrequired
base_price_centsintegerrequired
intervalstring | null
Example
{
  "id": 0,
  "name": "string",
  "slug": "string",
  "base_price_cents": 0,
  "interval": "string"
}

OAuthPopupContext

object
accountsArray<OAuthPopupAccount>required
Show child attributes
idintegerrequired
namestringrequired
accessAccountAccess
Show child attributes
sourcestringownermembershipplatform_admindelegatedmanagement_credentialapi_keyshopifyrequired
delegatedbooleanrequired
manager_account_idinteger
manager_account_namestring | null
management_grant_idinteger
permission_setstringoperator_v1
credential_typestringmanagement
can_manageboolean
needs_subscribebooleanrequired
plansArray<OAuthPopupPlan>required
Show child attributes
idintegerrequired
namestringrequired
slugstringrequired
base_price_centsintegerrequired
intervalstring | null
stripe_publishable_keystring | null
Example
{
  "accounts": [
    {
      "id": 0,
      "name": "string",
      "access": {
        "source": "owner",
        "delegated": true,
        "manager_account_id": 0,
        "manager_account_name": "string",
        "management_grant_id": 0,
        "permission_set": "operator_v1",
        "credential_type": "management"
      },
      "can_manage": true,
      "needs_subscribe": true
    }
  ],
  "plans": [
    {
      "id": 0,
      "name": "string",
      "slug": "string",
      "base_price_cents": 0,
      "interval": "string"
    }
  ],
  "stripe_publishable_key": "string"
}

OAuthPopupSubscribeRequest

object
plan_idintegerrequired
account_idinteger | null
stripe_tokenstring | null
Example
{
  "plan_id": 0,
  "account_id": 0,
  "stripe_token": "string"
}

OAuthPopupSubscribeResponse

object
next_stepstringconsentrequired
Example
{
  "next_step": "consent"
}

OAuthLaunchRequest

object
providerstringgoogle_oauth2githubrequired
auth_intentstringappagentapp
auth_stepstringloginsignuplogin
resume_urlstring<uri> | null

Required when auth_intent=agent; must point to the frontend /oauth/connect route.

Example
{
  "provider": "google_oauth2",
  "auth_intent": "app",
  "auth_step": "login",
  "resume_url": "https://example.com"
}

OAuthLaunchResponse

object
launch_urlstring<uri>required
Example
{
  "launch_url": "https://example.com"
}

Brand

object
idinteger
sidstringread only

Public secure identifier (non-sequential)

account_idinteger
brand_colorstring | null
text_colorstring | null
bg_colorstring | null
radiusinteger | null[0, 64]
spacing_densitystring | nullcompactnormalspacious
font_headingstring | null
font_bodystring | null
heading_sizeinteger | null[12, 48]
body_sizeinteger | null[12, 20]
brand_documentstring | null
company_descriptionstring | null
default_headerobject | null
default_footerobject | null
default_themeobject | null
physical_addressstring | null
company_namestring | null
source_urlstring | null
last_scraped_atstring<date-time> | null
linksArray<object> | null
Show child attributes
urlstring
iconstring
titlestring
logostring | null

Logo URL

completeboolean

True when brand_color and company_name are set

email_from_namestring | null
email_from_emailstring | null
email_reply_tostring | null
from_email_domain_statusstringblankverifiedunverified

Authorization state of the configured visible From address.

effective_from_emailstring<email> | nullread only
effective_reply_tostring<email> | nullread only
effective_sending_domainstring | nullread only
effective_source_emailstring<email> | nullread only
sender_configuredbooleanread only
email_view_onlineboolean

Default-off brand setting that injects a campaign view-in-browser link when a verified tracking domain is available.

email_track_opensboolean

Default-on brand setting. When false, this brand's emails carry no open-tracking pixel and opens from mail already sent are not recorded.

email_track_clicksboolean

Default-on brand setting. When false, this brand's links are not rewritten and clicks from mail already sent are not recorded; delivered links keep working.

test_email_recipientsArray<string>
onboarding_stateobject

JSONB — keys are step names, values are completion metadata

onboardingobject
Show child attributes
stepsobject

Current state of each onboarding step

progressobject
Show child attributes
completedinteger
totalinteger
domain_verifiedboolean
can_sendboolean
brand_subdomainBrandSubdomain | null
byo_routingobject

Warns when the brand has connected its own (BYO) email provider but verified sending domains still route through Nitrosend's hosted provider. Read-only; never blocks a send. mismatch is false (and message null) when all is well.

Show child attributes
mismatchboolean
providerstring | null

The connected BYO provider, e.g. ses.

bypassing_domainsArray<string>

Verified domains still sending through Nitrosend's hosted provider.

messagestring | null
subscribed_contacts_countinteger

Count of subscribed contacts in this brand, recounted in the background at most every 10 minutes while the brand is listed or fetched.

logo_urlstring<uri> | nullread only
screenshot_urlstring<uri> | nullread only
capabilitiesobject
sms_provisionedbooleanread only
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "sid": "string",
  "account_id": 0,
  "brand_color": "string",
  "text_color": "string",
  "bg_color": "string",
  "radius": 0,
  "spacing_density": "compact",
  "font_heading": "string",
  "font_body": "string",
  "heading_size": 12,
  "body_size": 12,
  "brand_document": "string",
  "company_description": "string",
  "default_header": {},
  "default_footer": {},
  "default_theme": {},
  "physical_address": "string",
  "company_name": "string",
  "source_url": "string",
  "last_scraped_at": "2024-01-15T09:30:00Z",
  "links": [
    {
      "url": "string",
      "icon": "string",
      "title": "string"
    }
  ],
  "logo": "string",
  "complete": true,
  "email_from_name": "string",
  "email_from_email": "string",
  "email_reply_to": "string",
  "from_email_domain_status": "blank",
  "effective_from_email": "user@example.com",
  "effective_reply_to": "user@example.com",
  "effective_sending_domain": "string",
  "effective_source_email": "user@example.com",
  "sender_configured": true,
  "email_view_online": true,
  "email_track_opens": true,
  "email_track_clicks": true,
  "test_email_recipients": [
    "user@example.com"
  ],
  "onboarding_state": {},
  "onboarding": {
    "steps": {},
    "progress": {
      "completed": 0,
      "total": 0
    }
  },
  "domain_verified": true,
  "can_send": true,
  "brand_subdomain": {
    "namespace_status": "unreserved",
    "status": "brand_identity_required",
    "ready": true,
    "selected": true,
    "preparation_required": true,
    "from_email": "user@example.com",
    "fqdn": "string",
    "apex": "string",
    "local_part": "string",
    "local_part_editable": true,
    "fqdn_changeable": false,
    "suggested_subdomain": "string"
  },
  "byo_routing": {
    "mismatch": true,
    "provider": "string",
    "bypassing_domains": [
      "string"
    ],
    "message": "string"
  },
  "subscribed_contacts_count": 0,
  "logo_url": "https://example.com",
  "screenshot_url": "https://example.com",
  "capabilities": {},
  "sms_provisioned": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

BrandSubdomain

object
namespace_statusstringunreservedactivereplacement_pendingretiringretiredrequired
statusstringbrand_identity_requiredbrand_identity_review_requirednamespace_reservation_requirednot_materializedroot_unavailablereadyunavailablerequired
readybooleanrequired
selectedboolean
preparation_requiredbooleanrequired
from_emailstring<email>
fqdnstring
apexstring
local_partstring
local_part_editableboolean
fqdn_changeableboolean
suggested_subdomainstring | null

Candidate offered while the brand has no namespace (namespace_status: unreserved): derived from the company name, or from the account owner while the Brand Kit is incomplete. Absent once a name is reserved, because an allocated name never changes, and absent when nothing safe can be derived.

Example
{
  "namespace_status": "unreserved",
  "status": "brand_identity_required",
  "ready": true,
  "selected": true,
  "preparation_required": true,
  "from_email": "user@example.com",
  "fqdn": "string",
  "apex": "string",
  "local_part": "string",
  "local_part_editable": true,
  "fqdn_changeable": false,
  "suggested_subdomain": "string"
}

BrandSubdomainPreparationResponse

object
statusstringreadyunavailablerequired
brand_subdomainBrandSubdomainrequired
Show child attributes
namespace_statusstringunreservedactivereplacement_pendingretiringretiredrequired
statusstringbrand_identity_requiredbrand_identity_review_requirednamespace_reservation_requirednot_materializedroot_unavailablereadyunavailablerequired
readybooleanrequired
selectedboolean
preparation_requiredbooleanrequired
from_emailstring<email>
fqdnstring
apexstring
local_partstring
local_part_editableboolean
fqdn_changeableboolean
suggested_subdomainstring | null

Candidate offered while the brand has no namespace (namespace_status: unreserved): derived from the company name, or from the account owner while the Brand Kit is incomplete. Absent once a name is reserved, because an allocated name never changes, and absent when nothing safe can be derived.

Example
{
  "status": "ready",
  "brand_subdomain": {
    "namespace_status": "unreserved",
    "status": "brand_identity_required",
    "ready": true,
    "selected": true,
    "preparation_required": true,
    "from_email": "user@example.com",
    "fqdn": "string",
    "apex": "string",
    "local_part": "string",
    "local_part_editable": true,
    "fqdn_changeable": false,
    "suggested_subdomain": "string"
  }
}

AudienceReachFit

object
plan_idintegerrequired
slugstringrequired
namestringrequired
tier_groupstringrequired
daily_capinteger | null

Recipients per 24 hours at the account's sending standing; null when unlimited

capacityinteger | null

Emails available within the month: what remains on the current plan, the first month's allowance on a candidate; null when unlimited

days_to_reachinteger | null

Days until everyone has been reached once; null when the month cannot hold the send

coversbooleanrequired

Whether one full send to the audience fits within the month

Example
{
  "plan_id": 0,
  "slug": "string",
  "name": "string",
  "tier_group": "string",
  "daily_cap": 0,
  "capacity": 0,
  "days_to_reach": 0,
  "covers": true
}

AudienceReach

object
audienceintegerrequired
cohortstringrequired

The account's deliverability cohort the daily caps are read at

currentAudienceReachFit | null

The current plan; null when the account has no subscription

recommendedAudienceReachFit | null

The cheapest listed plan above the current one whose first month holds the send; null when the current plan covers it or no listed plan would

coveredbooleanrequired

Whether the current plan covers a full send

summarystring | null

The one sentence every surface shows; null when covered

Example
{
  "audience": 0,
  "cohort": "string",
  "current": {
    "plan_id": 0,
    "slug": "string",
    "name": "string",
    "tier_group": "string",
    "daily_cap": 0,
    "capacity": 0,
    "days_to_reach": 0,
    "covers": true
  },
  "recommended": {
    "plan_id": 0,
    "slug": "string",
    "name": "string",
    "tier_group": "string",
    "daily_cap": 0,
    "capacity": 0,
    "days_to_reach": 0,
    "covers": true
  },
  "covered": true,
  "summary": "string"
}

HostedSenderAvailability

object
subdomainstringrequired

The normalised label that would be reserved (or the input when unsafe)

fqdnstring | null
availablebooleanrequired
reasonstring | nulltakenunsafereservedlocal_part_invalid

Why the address is unavailable; null when available

local_partstring | null

The normalised local part that would be reserved (the allocator's default when none was given), or the input when it is invalid.

from_emailstring | null

The exact address that would be reserved; null when unavailable for a policy reason

Example
{
  "subdomain": "string",
  "fqdn": "string",
  "available": true,
  "reason": "taken",
  "local_part": "string",
  "from_email": "string"
}

BrandDeletionSafetyImpact

object
contactsinteger>= 0required
campaignsinteger>= 0required
flowsinteger>= 0required
templatesinteger>= 0required
domainsinteger>= 0required
messagesinteger>= 0required
Example
{
  "contacts": 0,
  "campaigns": 0,
  "flows": 0,
  "templates": 0,
  "domains": 0,
  "messages": 0
}

BrandDeletionSafetyActiveSends

object
queued_messagesinteger>= 0required
active_campaignsinteger>= 0required

Scheduled or live campaigns.

Example
{
  "queued_messages": 0,
  "active_campaigns": 0
}

BrandDeletionSafety

object
deletion_impactBrandDeletionSafetyImpactrequired
Show child attributes
contactsinteger>= 0required
campaignsinteger>= 0required
flowsinteger>= 0required
templatesinteger>= 0required
domainsinteger>= 0required
messagesinteger>= 0required
active_sendsBrandDeletionSafetyActiveSendsrequired
Show child attributes
queued_messagesinteger>= 0required
active_campaignsinteger>= 0required

Scheduled or live campaigns.

can_deletebooleanrequired

True when no force confirmation is required.

requires_forcebooleanrequired

True when active sends require force=true to delete.

Example
{
  "deletion_impact": {
    "contacts": 0,
    "campaigns": 0,
    "flows": 0,
    "templates": 0,
    "domains": 0,
    "messages": 0
  },
  "active_sends": {
    "queued_messages": 0,
    "active_campaigns": 0
  },
  "can_delete": true,
  "requires_force": true
}

AffiliateCenterPayload

object
enrolledbooleanrequired

Whether the account is linked to a Rewardful affiliate.

availablebooleanrequired

Whether live affiliate data or setup is currently available.

statestring | nullactivepausedunavailable
setup_statusstring | nullpendingneeds_detailsunavailable

Present only while an entitled, unlinked account is being reconciled.

share_urlstring<uri> | null
statsobject
Show child attributes
visitorsinteger>= 0
leadsinteger>= 0
conversionsinteger>= 0
earningsobject
Show child attributes
knownboolean
total_centsinteger | null
currencystring
Example
{
  "enrolled": true,
  "available": true,
  "state": "active",
  "setup_status": "pending",
  "share_url": "https://example.com",
  "stats": {
    "visitors": 0,
    "leads": 0,
    "conversions": 0
  },
  "earnings": {
    "known": true,
    "total_cents": 0,
    "currency": "string"
  }
}

SetupCenterPayload

object
cardsArray<SetupCenterCard>
Show child attributes
idstringbrand_kit_scandnsimport_subscribersconnect_agent
completeboolean
acknowledgedboolean
acknowledged_atstring<date-time> | null
sectionsobject
Show child attributes
requiredArray<string>
recommendedArray<string>
progressobject

Each of the four cards counts individually; total is always 4 so every client surface shows the same "N of 4".

Show child attributes
completedinteger
totalinteger
seenboolean
dismissedboolean
completeboolean
establishedboolean

True when the brand is demonstrably operating: a real email send on a verified sending domain, or two or more distinct campaigns sent. Independent of complete — an established brand may still carry incomplete cards it has chosen to skip. Clients use it to retire setup nudges.

Example
{
  "cards": [
    {
      "id": "brand_kit_scan",
      "complete": true,
      "acknowledged": true,
      "acknowledged_at": "2024-01-15T09:30:00Z"
    }
  ],
  "sections": {
    "required": [
      "string"
    ],
    "recommended": [
      "string"
    ]
  },
  "progress": {
    "completed": 0,
    "total": 0
  },
  "seen": true,
  "dismissed": true,
  "complete": true,
  "established": true
}

SetupCenterCard

object
idstringbrand_kit_scandnsimport_subscribersconnect_agent
completeboolean
acknowledgedboolean
acknowledged_atstring<date-time> | null
Example
{
  "id": "brand_kit_scan",
  "complete": true,
  "acknowledged": true,
  "acknowledged_at": "2024-01-15T09:30:00Z"
}

FieldCatalog

object
idintegerrequired
keystringrequired

Dot-separated field key. Typed contact columns use the bare column name (e.g. email, first_name). JSONB data keys are prefixed with data. (e.g. data.plan, data.apollo.title, data.hubspot.company, data.tags).

categorystringcontactcustomenrichmentengagementtagrequired

Derived from the key namespace.

  • contact — typed column on the contacts table
  • tag — data.tags array
  • enrichment — reserved enrichment namespaces such as data.apollo.*, data.pdl.*, data.attio.*, data.hubspot.*, data.stripe.*, data.shopify.*, and derived data.nitro.*
  • custom — any other data.* key
  • engagement — future engagement traits (reserved)
field_typestringstringnumberbooleandateenumrequired

Inferred from the first observed value; pinned and never flipped.

presentation_typestringtextnumbercurrencypercentdatedatetimebooleanenumrequired

Shared presentation contract used by fact displays and generated merge tags.

presentation_optionsobjectrequired

Provider-supplied formatting metadata such as decimal precision, currency-code field path, unit scale, or percentage multiplier.

labelstringrequired

Human-readable label. Defaults to a humanised version of the key.

display_labelstring

Source-qualified field label suitable for display.

source_keystring | null
source_namestring | null
object_labelstring | null
source_field_labelstring | null
merge_tagstring | null

Ready-to-insert merge tag for a scalar custom or projected integration field. Typed fields include the deterministic presentation filter used by preview, test, and delivery rendering.

promotedbooleanrequired

Whether this field is pinned as a default column in the contacts grid.

fill_ratestring | null

Percentage of contacts that have a non-null value for this field. Computed asynchronously; may be null if the refresh job has not run yet.

fill_rate_refreshed_atstring<date-time> | null

When fill_rate was last computed.

created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "key": "string",
  "category": "contact",
  "field_type": "string",
  "presentation_type": "text",
  "presentation_options": {},
  "label": "string",
  "display_label": "string",
  "source_key": "string",
  "source_name": "string",
  "object_label": "string",
  "source_field_label": "string",
  "merge_tag": "string",
  "promoted": true,
  "fill_rate": "75.0",
  "fill_rate_refreshed_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

DeliveryCapacity

object
sourcestringplanoperator_override
window_secondsinteger
statusstringknownunlimitednot_applicableunknowndegradedrequired
limitinteger | null>= 0required
reservedinteger | null>= 0required
acceptedinteger | null>= 0required
provider_unknowninteger | null>= 0required
remaininginteger | null>= 0required
Example
{
  "source": "plan",
  "window_seconds": 86400,
  "status": "known",
  "limit": 0,
  "reserved": 0,
  "accepted": 0,
  "provider_unknown": 0,
  "remaining": 0
}

DeliveryPacingScope

object
typestringrequired
statusstringreadydeferredrequired
next_dispatch_atstring<date-time>
minimum_interval_secondsnumber>= 0required
feedback_epochinteger>= 0required
Example
{
  "type": "string",
  "status": "ready",
  "next_dispatch_at": "2024-01-15T09:30:00Z",
  "minimum_interval_seconds": 0,
  "feedback_epoch": 0
}

DeliveryPacingState

object
statusstringreadydeferredrequired
policy_versionstringrequired
queued_quantityinteger>= 0
next_dispatch_atstring<date-time>
scopesArray<DeliveryPacingScope>required
Show child attributes
typestringrequired
statusstringreadydeferredrequired
next_dispatch_atstring<date-time>
minimum_interval_secondsnumber>= 0required
feedback_epochinteger>= 0required
Example
{
  "status": "ready",
  "policy_version": "string",
  "queued_quantity": 0,
  "next_dispatch_at": "2024-01-15T09:30:00Z",
  "scopes": [
    {
      "type": "string",
      "status": "ready",
      "next_dispatch_at": "2024-01-15T09:30:00Z",
      "minimum_interval_seconds": 0,
      "feedback_epoch": 0
    }
  ]
}

DeliveryStatusIssue

object
controlstringaccount_statusbrandsender_identitycommercial_capacityrequired
reason_codestringsending_pausedbrand_unavailablesender_not_readysending_capacity_reacheddelivery_evidence_pendingrequired
retryablebooleanrequired
retry_atstring<date-time>
Example
{
  "control": "account_status",
  "reason_code": "sending_paused",
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z"
}

DeliveryStatus

object
assessment_scopestringrequired
admission_statusstringalloweddeferreddeniedrequired
sending_pauseSendingPause

What the owner of a suspended account is told. A deliverability pause names the metric and the fix (reason, what_to_do). Any other suspension is opaque and carries no reason. Recovery actions reach the existing support channel.

Show child attributes
sending_pausedbooleantruerequired
reasonstringcritical_bounce_ratecritical_complaint_rate

Present only for an explained deliverability pause.

occurred_atstring<date-time>required
headlinestringrequired
detailstringrequired
what_to_doArray<string>

Present only for an explained deliverability pause.

request_reviewstringrequired

The instruction an agent relays to the owner.

recovery_actionsArray<object>required
Show child attributes
typestringverify_listrequest_reviewcontact_supportrequired
labelstringrequired
urlstringrequired

App link or support mailto.

commercial_capacityDeliveryCapacityrequired
Show child attributes
sourcestringplanoperator_override
window_secondsinteger
statusstringknownunlimitednot_applicableunknowndegradedrequired
limitinteger | null>= 0required
reservedinteger | null>= 0required
acceptedinteger | null>= 0required
provider_unknowninteger | null>= 0required
remaininginteger | null>= 0required
capacity_recoveryDeliveryCapacityRecovery

Informational recovery at 80 percent used, exhaustion, or when a campaign exceeds remaining allowance. Never denies a send or promises that payment or verification bypasses safety. Actions come from the shared backend projection; only offer verification when new valid proof can improve standing.

Show child attributes
statestringapproachingreachedcampaign_exceeds_remainingrequired
reason_codestringsending_capacity_warningsending_capacity_reachedrequired
blocking_controlstringcommercial_capacityrequired
usage_percentinteger[0, 100]required
requested_quantityinteger>= 0
labelstringrequired
detailstringrequired
capacityDeliveryCapacityrequired
Show child attributes
sourcestringplanoperator_override
window_secondsinteger
statusstringknownunlimitednot_applicableunknowndegradedrequired
limitinteger | null>= 0required
reservedinteger | null>= 0required
acceptedinteger | null>= 0required
provider_unknowninteger | null>= 0required
remaininginteger | null>= 0required
upgrade_urlstring<uri>

Shareable account-specific plan link. Authentication and billing permissions still apply.

retry_atstring<date-time>

Recorded retry time, not a guarantee that delivery completes then.

recovery_actionDeliveryCapacityRecoveryActionrequired
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
recovery_actionsArray<DeliveryCapacityRecoveryAction>required
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
owner_actionDeliveryCapacityRecoveryActionrequired
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
pacing_stateDeliveryPacingStaterequired
Show child attributes
statusstringreadydeferredrequired
policy_versionstringrequired
queued_quantityinteger>= 0
next_dispatch_atstring<date-time>
scopesArray<DeliveryPacingScope>required
Show child attributes
typestringrequired
statusstringreadydeferredrequired
next_dispatch_atstring<date-time>
minimum_interval_secondsnumber>= 0required
feedback_epochinteger>= 0required
blocking_controlstringaccount_statusbrandsender_identitycommercial_capacity
reason_codestring
issuesArray<DeliveryStatusIssue>required
Show child attributes
controlstringaccount_statusbrandsender_identitycommercial_capacityrequired
reason_codestringsending_pausedbrand_unavailablesender_not_readysending_capacity_reacheddelivery_evidence_pendingrequired
retryablebooleanrequired
retry_atstring<date-time>
retry_atstring<date-time>
observed_atstring<date-time>required
Example
{
  "assessment_scope": "account_capacity",
  "admission_status": "allowed",
  "sending_pause": {
    "sending_paused": true,
    "reason": "critical_bounce_rate",
    "occurred_at": "2024-01-15T09:30:00Z",
    "headline": "string",
    "detail": "string",
    "what_to_do": [
      "string"
    ],
    "request_review": "string",
    "recovery_actions": [
      {
        "type": "verify_list",
        "label": "string",
        "url": "string"
      }
    ]
  },
  "commercial_capacity": {
    "source": "plan",
    "window_seconds": 86400,
    "status": "known",
    "limit": 0,
    "reserved": 0,
    "accepted": 0,
    "provider_unknown": 0,
    "remaining": 0
  },
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "pacing_state": {
    "status": "ready",
    "policy_version": "string",
    "queued_quantity": 0,
    "next_dispatch_at": "2024-01-15T09:30:00Z",
    "scopes": [
      {
        "type": "string",
        "status": "ready",
        "next_dispatch_at": "2024-01-15T09:30:00Z",
        "minimum_interval_seconds": 0,
        "feedback_epoch": 0
      }
    ]
  },
  "blocking_control": "account_status",
  "reason_code": "string",
  "issues": [
    {
      "control": "account_status",
      "reason_code": "sending_paused",
      "retryable": true,
      "retry_at": "2024-01-15T09:30:00Z"
    }
  ],
  "retry_at": "2024-01-15T09:30:00Z",
  "observed_at": "2024-01-15T09:30:00Z"
}

DeliveryCapacityRecovery

object

Informational recovery at 80 percent used, exhaustion, or when a campaign exceeds remaining allowance. Never denies a send or promises that payment or verification bypasses safety. Actions come from the shared backend projection; only offer verification when new valid proof can improve standing.

statestringapproachingreachedcampaign_exceeds_remainingrequired
reason_codestringsending_capacity_warningsending_capacity_reachedrequired
blocking_controlstringcommercial_capacityrequired
usage_percentinteger[0, 100]required
requested_quantityinteger>= 0
labelstringrequired
detailstringrequired
capacityDeliveryCapacityrequired
Show child attributes
sourcestringplanoperator_override
window_secondsinteger
statusstringknownunlimitednot_applicableunknowndegradedrequired
limitinteger | null>= 0required
reservedinteger | null>= 0required
acceptedinteger | null>= 0required
provider_unknowninteger | null>= 0required
remaininginteger | null>= 0required
upgrade_urlstring<uri>

Shareable account-specific plan link. Authentication and billing permissions still apply.

retry_atstring<date-time>

Recorded retry time, not a guarantee that delivery completes then.

recovery_actionDeliveryCapacityRecoveryActionrequired
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
recovery_actionsArray<DeliveryCapacityRecoveryAction>required
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
owner_actionDeliveryCapacityRecoveryActionrequired
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
Example
{
  "state": "approaching",
  "reason_code": "sending_capacity_warning",
  "blocking_control": "commercial_capacity",
  "usage_percent": 0,
  "requested_quantity": 0,
  "label": "string",
  "detail": "string",
  "capacity": {
    "source": "plan",
    "window_seconds": 86400,
    "status": "known",
    "limit": 0,
    "reserved": 0,
    "accepted": 0,
    "provider_unknown": 0,
    "remaining": 0
  },
  "upgrade_url": "https://example.com",
  "retry_at": "2024-01-15T09:30:00Z",
  "recovery_action": {
    "type": "upgrade_plan",
    "label": "string",
    "detail": "string",
    "url": "https://example.com",
    "required_role": "account_owner_or_admin"
  },
  "recovery_actions": [
    {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  ],
  "owner_action": {
    "type": "upgrade_plan",
    "label": "string",
    "detail": "string",
    "url": "https://example.com",
    "required_role": "account_owner_or_admin"
  }
}

DeliveryCapacityRecoveryAction

object
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
Example
{
  "type": "upgrade_plan",
  "label": "string",
  "detail": "string",
  "url": "https://example.com",
  "required_role": "account_owner_or_admin"
}

ValidationAudience

object
One of
any
any
any
any
any

ValidationOperationCounts

object
candidate_countinteger>= 0required
deduplicated_countinteger>= 0required
cached_countinteger>= 0required
ineligible_countinteger>= 0required
eligible_countinteger>= 0required
pending_countinteger>= 0
executing_countinteger>= 0
billable_countinteger>= 0
not_billable_countinteger>= 0
provider_unknown_countinteger>= 0
failed_countinteger>= 0
Example
{
  "candidate_count": 0,
  "deduplicated_count": 0,
  "cached_count": 0,
  "ineligible_count": 0,
  "eligible_count": 0,
  "pending_count": 0,
  "executing_count": 0,
  "billable_count": 0,
  "not_billable_count": 0,
  "provider_unknown_count": 0,
  "failed_count": 0
}

ValidationOperationPricing

object
price_book_versionstringrequired
unit_rate_centsstringrequired
maximum_charge_centsinteger>= 0required
committed_centsinteger>= 0
released_centsinteger>= 0
currencystringrequired
quote_digeststring
expires_atstring<date-time>required
execution_deadline_atstring<date-time> | null
Example
{
  "price_book_version": "string",
  "unit_rate_cents": "string",
  "maximum_charge_cents": 0,
  "committed_cents": 0,
  "released_cents": 0,
  "currency": "string",
  "quote_digest": "string",
  "expires_at": "2024-01-15T09:30:00Z",
  "execution_deadline_at": "2024-01-15T09:30:00Z"
}

ValidationOperationFunding

object
routestringrequired
availablebooleanrequired
reasonstring
usage_event_idinteger
statestringneeds_fundingheldcommittedreleased
recoveryobject
Example
{
  "route": "direct_prepaid",
  "available": true,
  "reason": "string",
  "usage_event_id": 0,
  "state": "needs_funding",
  "recovery": {}
}

ValidationOperationQuote

object
statusstringquotedneeds_fundingrequired
source_kindstringcontact_channelcontactlistsegmentall_contactsrequired
quote_digeststringrequired
countsValidationOperationCountsrequired
Show child attributes
candidate_countinteger>= 0required
deduplicated_countinteger>= 0required
cached_countinteger>= 0required
ineligible_countinteger>= 0required
eligible_countinteger>= 0required
pending_countinteger>= 0
executing_countinteger>= 0
billable_countinteger>= 0
not_billable_countinteger>= 0
provider_unknown_countinteger>= 0
failed_countinteger>= 0
pricingValidationOperationPricingrequired
Show child attributes
price_book_versionstringrequired
unit_rate_centsstringrequired
maximum_charge_centsinteger>= 0required
committed_centsinteger>= 0
released_centsinteger>= 0
currencystringrequired
quote_digeststring
expires_atstring<date-time>required
execution_deadline_atstring<date-time> | null
fundingValidationOperationFundingrequired
Show child attributes
routestringrequired
availablebooleanrequired
reasonstring
usage_event_idinteger
statestringneeds_fundingheldcommittedreleased
recoveryobject
spendSpendProjectionrequired
Show child attributes
schemastringrequired
statusstringreadyneeds_fundingpayment_pendingblockedunavailablerequired
routestringdirect_prepaidincludedpostpaidshopifyvercellegacyrequired
currencystringrequired
maximum_charge_centsinteger>= 0required
balanceSpendBalance
Show child attributes
available_centsintegerrequired
reserved_centsinteger>= 0required
shortfall_centsinteger>= 0required
fundingobjectrequired

Canonical account funding projection from Billing::Funding::Presenter.

recovery_actionSpendRecoveryActionrequired
Show child attributes
typestringadd_fundsretry_add_fundscomplete_checkoutwait_for_paymentask_account_adminmanage_in_shopifymanage_in_marketplacecontact_supportunavailable
reasonstring
operationstringadd_funds
urlstring<uri>
purchase_idinteger
shortfall_centsinteger>= 0
minimum_centsinteger>= 0
maximum_centsinteger>= 0
recommended_centsinteger>= 0
preset_centsArray<integer>
mutationbooleanrequired
Example
{
  "status": "quoted",
  "source_kind": "contact_channel",
  "quote_digest": "string",
  "counts": {
    "candidate_count": 0,
    "deduplicated_count": 0,
    "cached_count": 0,
    "ineligible_count": 0,
    "eligible_count": 0,
    "pending_count": 0,
    "executing_count": 0,
    "billable_count": 0,
    "not_billable_count": 0,
    "provider_unknown_count": 0,
    "failed_count": 0
  },
  "pricing": {
    "price_book_version": "string",
    "unit_rate_cents": "string",
    "maximum_charge_cents": 0,
    "committed_cents": 0,
    "released_cents": 0,
    "currency": "string",
    "quote_digest": "string",
    "expires_at": "2024-01-15T09:30:00Z",
    "execution_deadline_at": "2024-01-15T09:30:00Z"
  },
  "funding": {
    "route": "direct_prepaid",
    "available": true,
    "reason": "string",
    "usage_event_id": 0,
    "state": "needs_funding",
    "recovery": {}
  },
  "spend": {
    "schema": "nitrosend.spend.v1",
    "status": "ready",
    "route": "direct_prepaid",
    "currency": "string",
    "maximum_charge_cents": 0,
    "balance": {
      "available_cents": 0,
      "reserved_cents": 0,
      "shortfall_cents": 0
    },
    "funding": {},
    "recovery_action": {
      "type": "add_funds",
      "reason": "string",
      "operation": "add_funds",
      "url": "https://example.com",
      "purchase_id": 0,
      "shortfall_cents": 0,
      "minimum_cents": 0,
      "maximum_cents": 0,
      "recommended_cents": 0,
      "preset_cents": [
        0
      ]
    }
  },
  "mutation": false
}

ValidationOperation

object
operation_idstringrequired
statusstringrequestedquotedheldexecutingpartially_committedcommittedreleasedneeds_fundingfailedrequired
source_kindstringcontact_channelcontactlistsegmentall_contactsrequired
item_detailobjectrequired
Show child attributes
statusstringavailablecompactedrequired
compacted_atstring<date-time>
item_countinteger>= 0
countsValidationOperationCountsrequired
Show child attributes
candidate_countinteger>= 0required
deduplicated_countinteger>= 0required
cached_countinteger>= 0required
ineligible_countinteger>= 0required
eligible_countinteger>= 0required
pending_countinteger>= 0
executing_countinteger>= 0
billable_countinteger>= 0
not_billable_countinteger>= 0
provider_unknown_countinteger>= 0
failed_countinteger>= 0
pricingValidationOperationPricingrequired
Show child attributes
price_book_versionstringrequired
unit_rate_centsstringrequired
maximum_charge_centsinteger>= 0required
committed_centsinteger>= 0
released_centsinteger>= 0
currencystringrequired
quote_digeststring
expires_atstring<date-time>required
execution_deadline_atstring<date-time> | null
fundingValidationOperationFundingrequired
Show child attributes
routestringrequired
availablebooleanrequired
reasonstring
usage_event_idinteger
statestringneeds_fundingheldcommittedreleased
recoveryobject
spendSpendProjectionrequired
Show child attributes
schemastringrequired
statusstringreadyneeds_fundingpayment_pendingblockedunavailablerequired
routestringdirect_prepaidincludedpostpaidshopifyvercellegacyrequired
currencystringrequired
maximum_charge_centsinteger>= 0required
balanceSpendBalance
Show child attributes
available_centsintegerrequired
reserved_centsinteger>= 0required
shortfall_centsinteger>= 0required
fundingobjectrequired

Canonical account funding projection from Billing::Funding::Presenter.

recovery_actionSpendRecoveryActionrequired
Show child attributes
typestringadd_fundsretry_add_fundscomplete_checkoutwait_for_paymentask_account_adminmanage_in_shopifymanage_in_marketplacecontact_supportunavailable
reasonstring
operationstringadd_funds
urlstring<uri>
purchase_idinteger
shortfall_centsinteger>= 0
minimum_centsinteger>= 0
maximum_centsinteger>= 0
recommended_centsinteger>= 0
preset_centsArray<integer>
failure_codestring
started_atstring<date-time>
completed_atstring<date-time>
next_actionstring
Example
{
  "operation_id": "string",
  "status": "requested",
  "source_kind": "contact_channel",
  "item_detail": {
    "status": "available",
    "compacted_at": "2024-01-15T09:30:00Z",
    "item_count": 0
  },
  "counts": {
    "candidate_count": 0,
    "deduplicated_count": 0,
    "cached_count": 0,
    "ineligible_count": 0,
    "eligible_count": 0,
    "pending_count": 0,
    "executing_count": 0,
    "billable_count": 0,
    "not_billable_count": 0,
    "provider_unknown_count": 0,
    "failed_count": 0
  },
  "pricing": {
    "price_book_version": "string",
    "unit_rate_cents": "string",
    "maximum_charge_cents": 0,
    "committed_cents": 0,
    "released_cents": 0,
    "currency": "string",
    "quote_digest": "string",
    "expires_at": "2024-01-15T09:30:00Z",
    "execution_deadline_at": "2024-01-15T09:30:00Z"
  },
  "funding": {
    "route": "direct_prepaid",
    "available": true,
    "reason": "string",
    "usage_event_id": 0,
    "state": "needs_funding",
    "recovery": {}
  },
  "spend": {
    "schema": "nitrosend.spend.v1",
    "status": "ready",
    "route": "direct_prepaid",
    "currency": "string",
    "maximum_charge_cents": 0,
    "balance": {
      "available_cents": 0,
      "reserved_cents": 0,
      "shortfall_cents": 0
    },
    "funding": {},
    "recovery_action": {
      "type": "add_funds",
      "reason": "string",
      "operation": "add_funds",
      "url": "https://example.com",
      "purchase_id": 0,
      "shortfall_cents": 0,
      "minimum_cents": 0,
      "maximum_cents": 0,
      "recommended_cents": 0,
      "preset_cents": [
        0
      ]
    }
  },
  "failure_code": "string",
  "started_at": "2024-01-15T09:30:00Z",
  "completed_at": "2024-01-15T09:30:00Z",
  "next_action": "string"
}

ValidationOperationItem

object
idintegerrequired
contact_channel_idintegerrequired
statusstringpendingexecutingbillablenot_billableprovider_unknownfailedrequired
billableboolean
providerstring
native_statusstring
verdictstring
failure_codestring
result_referenceobject
completed_atstring<date-time>
Example
{
  "id": 0,
  "contact_channel_id": 0,
  "status": "pending",
  "billable": true,
  "provider": "string",
  "native_status": "string",
  "verdict": "string",
  "failure_code": "string",
  "result_reference": {},
  "completed_at": "2024-01-15T09:30:00Z"
}

ContactEnrichmentQuote

object
selected_countintegerrequired
already_current_countintegerrequired
reusable_countintegerrequired
provider_required_countintegerrequired
unavailable_countintegerrequired
maximum_billable_outcomesintegerrequired
resourcestringcontact_profile_enrichment
unit_rate_centsstringrequired
maximum_charge_centsintegerrequired
currencystringUSDrequired
price_book_versionstringrequired
availablebooleanrequired
reasonstring | null
spendSpendProjectionrequired
Show child attributes
schemastringrequired
statusstringreadyneeds_fundingpayment_pendingblockedunavailablerequired
routestringdirect_prepaidincludedpostpaidshopifyvercellegacyrequired
currencystringrequired
maximum_charge_centsinteger>= 0required
balanceSpendBalance
Show child attributes
available_centsintegerrequired
reserved_centsinteger>= 0required
shortfall_centsinteger>= 0required
fundingobjectrequired

Canonical account funding projection from Billing::Funding::Presenter.

recovery_actionSpendRecoveryActionrequired
Show child attributes
typestringadd_fundsretry_add_fundscomplete_checkoutwait_for_paymentask_account_adminmanage_in_shopifymanage_in_marketplacecontact_supportunavailable
reasonstring
operationstringadd_funds
urlstring<uri>
purchase_idinteger
shortfall_centsinteger>= 0
minimum_centsinteger>= 0
maximum_centsinteger>= 0
recommended_centsinteger>= 0
preset_centsArray<integer>
Example
{
  "selected_count": 0,
  "already_current_count": 0,
  "reusable_count": 0,
  "provider_required_count": 0,
  "unavailable_count": 0,
  "maximum_billable_outcomes": 0,
  "resource": "contact_profile_enrichment",
  "unit_rate_cents": "string",
  "maximum_charge_cents": 0,
  "currency": "USD",
  "price_book_version": "string",
  "available": true,
  "reason": "string",
  "spend": {
    "schema": "nitrosend.spend.v1",
    "status": "ready",
    "route": "direct_prepaid",
    "currency": "string",
    "maximum_charge_cents": 0,
    "balance": {
      "available_cents": 0,
      "reserved_cents": 0,
      "shortfall_cents": 0
    },
    "funding": {},
    "recovery_action": {
      "type": "add_funds",
      "reason": "string",
      "operation": "add_funds",
      "url": "https://example.com",
      "purchase_id": 0,
      "shortfall_cents": 0,
      "minimum_cents": 0,
      "maximum_cents": 0,
      "recommended_cents": 0,
      "preset_cents": [
        0
      ]
    }
  }
}

SpendProjection

object
schemastringrequired
statusstringreadyneeds_fundingpayment_pendingblockedunavailablerequired
routestringdirect_prepaidincludedpostpaidshopifyvercellegacyrequired
currencystringrequired
maximum_charge_centsinteger>= 0required
balanceSpendBalance
Show child attributes
available_centsintegerrequired
reserved_centsinteger>= 0required
shortfall_centsinteger>= 0required
fundingobjectrequired

Canonical account funding projection from Billing::Funding::Presenter.

recovery_actionSpendRecoveryActionrequired
Show child attributes
typestringadd_fundsretry_add_fundscomplete_checkoutwait_for_paymentask_account_adminmanage_in_shopifymanage_in_marketplacecontact_supportunavailable
reasonstring
operationstringadd_funds
urlstring<uri>
purchase_idinteger
shortfall_centsinteger>= 0
minimum_centsinteger>= 0
maximum_centsinteger>= 0
recommended_centsinteger>= 0
preset_centsArray<integer>
Example
{
  "schema": "nitrosend.spend.v1",
  "status": "ready",
  "route": "direct_prepaid",
  "currency": "string",
  "maximum_charge_cents": 0,
  "balance": {
    "available_cents": 0,
    "reserved_cents": 0,
    "shortfall_cents": 0
  },
  "funding": {},
  "recovery_action": {
    "type": "add_funds",
    "reason": "string",
    "operation": "add_funds",
    "url": "https://example.com",
    "purchase_id": 0,
    "shortfall_cents": 0,
    "minimum_cents": 0,
    "maximum_cents": 0,
    "recommended_cents": 0,
    "preset_cents": [
      0
    ]
  }
}

PaidActionIntentCreate

object
adapter_keystringrequired
adapter_versionstringrequired
operation_idempotency_keystringrequired
state_payloadobjectrequired

Adapter-owned state, validated and encrypted before persistence.

Example
{
  "adapter_key": "string",
  "adapter_version": "string",
  "operation_idempotency_key": "string",
  "state_payload": {}
}

PaidActionIntent

object
idstringrequired

Opaque public continuation identifier.

schemastringrequired
statusstringopenawaiting_fundingready_to_resumeconsumedcancelledexpiredrequired
adapterobjectrequired
Show child attributes
keystringrequired
versionstringrequired
operation_idempotency_keystringrequired
original_quote_fingerprintstringrequired
current_quote_fingerprintstring
quote_changedboolean
state_payloadobject
quoteobject
expires_atstring<date-time>required
consumed_atstring<date-time> | null
cancelled_atstring<date-time> | null
Example
{
  "id": "string",
  "schema": "nitrosend.paid_action_intent.v1",
  "status": "open",
  "adapter": {
    "key": "string",
    "version": "string"
  },
  "operation_idempotency_key": "string",
  "original_quote_fingerprint": "string",
  "current_quote_fingerprint": "string",
  "quote_changed": true,
  "state_payload": {},
  "quote": {},
  "expires_at": "2024-01-15T09:30:00Z",
  "consumed_at": "2024-01-15T09:30:00Z",
  "cancelled_at": "2024-01-15T09:30:00Z"
}

SpendBalance

object
available_centsintegerrequired
reserved_centsinteger>= 0required
shortfall_centsinteger>= 0required
Example
{
  "available_cents": 0,
  "reserved_cents": 0,
  "shortfall_cents": 0
}

SpendRecoveryAction

object
typestringadd_fundsretry_add_fundscomplete_checkoutwait_for_paymentask_account_adminmanage_in_shopifymanage_in_marketplacecontact_supportunavailable
reasonstring
operationstringadd_funds
urlstring<uri>
purchase_idinteger
shortfall_centsinteger>= 0
minimum_centsinteger>= 0
maximum_centsinteger>= 0
recommended_centsinteger>= 0
preset_centsArray<integer>
Example
{
  "type": "add_funds",
  "reason": "string",
  "operation": "add_funds",
  "url": "https://example.com",
  "purchase_id": 0,
  "shortfall_cents": 0,
  "minimum_cents": 0,
  "maximum_cents": 0,
  "recommended_cents": 0,
  "preset_cents": [
    0
  ]
}

ContactEnrichmentFundingRequired

object
codestringrequired
messagestringrequired
errorbooleanrequired
error_codestringrequired
currencystringrequired
required_centsinteger>= 0required
available_centsintegerrequired
reserved_centsinteger>= 0required
shortfall_centsinteger>= 0required
fundingobjectrequired
recovery_actionobjectrequired
spendSpendProjectionrequired
Show child attributes
schemastringrequired
statusstringreadyneeds_fundingpayment_pendingblockedunavailablerequired
routestringdirect_prepaidincludedpostpaidshopifyvercellegacyrequired
currencystringrequired
maximum_charge_centsinteger>= 0required
balanceSpendBalance
Show child attributes
available_centsintegerrequired
reserved_centsinteger>= 0required
shortfall_centsinteger>= 0required
fundingobjectrequired

Canonical account funding projection from Billing::Funding::Presenter.

recovery_actionSpendRecoveryActionrequired
Show child attributes
typestringadd_fundsretry_add_fundscomplete_checkoutwait_for_paymentask_account_adminmanage_in_shopifymanage_in_marketplacecontact_supportunavailable
reasonstring
operationstringadd_funds
urlstring<uri>
purchase_idinteger
shortfall_centsinteger>= 0
minimum_centsinteger>= 0
maximum_centsinteger>= 0
recommended_centsinteger>= 0
preset_centsArray<integer>
Example
{
  "code": "insufficient_balance",
  "message": "string",
  "error": true,
  "error_code": "insufficient_balance",
  "currency": "string",
  "required_cents": 0,
  "available_cents": 0,
  "reserved_cents": 0,
  "shortfall_cents": 0,
  "funding": {},
  "recovery_action": {},
  "spend": {
    "schema": "nitrosend.spend.v1",
    "status": "ready",
    "route": "direct_prepaid",
    "currency": "string",
    "maximum_charge_cents": 0,
    "balance": {
      "available_cents": 0,
      "reserved_cents": 0,
      "shortfall_cents": 0
    },
    "funding": {},
    "recovery_action": {
      "type": "add_funds",
      "reason": "string",
      "operation": "add_funds",
      "url": "https://example.com",
      "purchase_id": 0,
      "shortfall_cents": 0,
      "minimum_cents": 0,
      "maximum_cents": 0,
      "recommended_cents": 0,
      "preset_cents": [
        0
      ]
    }
  }
}

ContactEnrichmentDispatch

object
selected_countintegerrequired
queued_countintegerrequired
already_current_countintegerrequired
reusable_countintegerrequired
provider_required_countintegerrequired
unavailable_countintegerrequired
maximum_charge_centsintegerrequired
currencystringUSDrequired
price_book_versionstringrequired
idempotent_replaybooleanrequired
Example
{
  "selected_count": 0,
  "queued_count": 0,
  "already_current_count": 0,
  "reusable_count": 0,
  "provider_required_count": 0,
  "unavailable_count": 0,
  "maximum_charge_cents": 0,
  "currency": "USD",
  "price_book_version": "string",
  "idempotent_replay": true
}

Contact

object
idinteger
brand_idinteger | null
uuidstring<uuid>
first_namestring | null
last_namestring | null
sourcestring | null
country_codestring | null
flag_emojistring | null

Unicode regional-indicator emoji pair derived from country_code (e.g. "🇦🇺"). Null when country_code is blank.

dataobject

Custom key-value data. The reserved key tags holds an array of string labels used for segmentation and targeting. Reserved enrichment namespaces such as apollo, pdl, attio, hubspot, stripe, shopify, and derived nitro may appear when integrations or enrichment jobs write source-scoped data.

subscribed_phoneboolean
subscribed_emailboolean
emailstring<email> | null

Convenience value for the preferred email channel. Full channel detail remains in channels[].

subscribedobject

Denormalized subscription summary by channel family.

Show child attributes
emailboolean
phoneboolean
verification_statusstringverifiedsuppressedunverified
enrichment_statusstringenrichednot_enriched
mailbox_providerstringgmailappleoutlookcorporateunknown

Derived mailbox provider for the contact's primary email domain. Known consumer domains map to gmail, apple, or outlook; any other valid email domain maps to corporate; unknown means no email is present.

list_idsArray<integer>
last_interacted_atstring<date-time> | null
created_atstring<date-time>
updated_atstring<date-time>
engagementobject | null

Aggregated email engagement rollup for this contact. All fields are nil-safe: when no rollup row exists yet, rating is "never", counts are 0, rates and timestamps are null.

Show child attributes
ratingstringengagedwarmcoolingdormantnever

Five-tier engagement rating based on recency of opens and clicks.

emails_sentinteger
unique_opensinteger
clicksinteger
open_ratenumber<float> | null
click_ratenumber<float> | null
last_opened_atstring<date-time> | null
last_clicked_atstring<date-time> | null
channelsArray<ContactChannel>
Show child attributes
idinteger
contact_idinteger
kindstringemailphone
valuestring
subscribedboolean
verifiedboolean
opt_in_atstring<date-time> | null
opt_out_atstring<date-time> | null
sent_countinteger
fail_countinteger
dataobject
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "brand_id": 0,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "first_name": "string",
  "last_name": "string",
  "source": "string",
  "country_code": "string",
  "flag_emoji": "string",
  "data": {
    "tags": [
      "vip",
      "newsletter"
    ],
    "plan": "pro"
  },
  "subscribed_phone": true,
  "subscribed_email": true,
  "email": "user@example.com",
  "subscribed": {
    "email": true,
    "phone": true
  },
  "verification_status": "verified",
  "enrichment_status": "enriched",
  "mailbox_provider": "gmail",
  "list_ids": [
    0
  ],
  "last_interacted_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "engagement": {
    "rating": "engaged",
    "emails_sent": 0,
    "unique_opens": 0,
    "clicks": 0,
    "open_rate": 0,
    "click_rate": 0,
    "last_opened_at": "2024-01-15T09:30:00Z",
    "last_clicked_at": "2024-01-15T09:30:00Z"
  },
  "channels": [
    {
      "id": 0,
      "contact_id": 0,
      "kind": "email",
      "value": "string",
      "subscribed": true,
      "verified": true,
      "opt_in_at": "2024-01-15T09:30:00Z",
      "opt_out_at": "2024-01-15T09:30:00Z",
      "sent_count": 0,
      "fail_count": 0,
      "data": {},
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}

ContactChannel

object
idinteger
contact_idinteger
kindstringemailphone
valuestring
subscribedboolean
verifiedboolean
opt_in_atstring<date-time> | null
opt_out_atstring<date-time> | null
sent_countinteger
fail_countinteger
dataobject
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "contact_id": 0,
  "kind": "email",
  "value": "string",
  "subscribed": true,
  "verified": true,
  "opt_in_at": "2024-01-15T09:30:00Z",
  "opt_out_at": "2024-01-15T09:30:00Z",
  "sent_count": 0,
  "fail_count": 0,
  "data": {},
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

ImageAsset

object
media_kindstringimage
media_urlstring<uri>
image_urlstring<uri>
signed_idstring
filenamestring
content_typestring
byte_sizeinteger
widthinteger | null

Intrinsic pixel width when detectable.

heightinteger | null

Intrinsic pixel height when detectable.

Example
{
  "media_kind": "image",
  "media_url": "https://example.com",
  "image_url": "https://example.com",
  "signed_id": "string",
  "filename": "string",
  "content_type": "string",
  "byte_size": 0,
  "width": 0,
  "height": 0
}

ContactList

object
idinteger
account_idinteger
brand_idinteger | null
namestring
contacts_countinteger
segment_idinteger | null
staleboolean
last_populated_atstring<date-time> | null
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "name": "string",
  "contacts_count": 0,
  "segment_id": 0,
  "stale": true,
  "last_populated_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

ListDeleteWarning

object
campaign_namesArray<string>
flow_namesArray<string>
Example
{
  "campaign_names": [
    "string"
  ],
  "flow_names": [
    "string"
  ]
}

BulkListContactsRequest

object
actionstringaddremoverequired

Add existing contacts to the list or remove them from it.

emailsArray<string>required
Example
{
  "action": "add",
  "emails": [
    "user@example.com"
  ]
}

BulkListContactsResponse

object
actionstringaddremove
list_idinteger
addedinteger

Contacts newly added for add actions

removedinteger

Contacts removed for remove actions

already_in_listArray<string>
not_in_listArray<string>
not_foundArray<string>
invalid_emailsArray<string>
Example
{
  "action": "add",
  "list_id": 0,
  "added": 0,
  "removed": 0,
  "already_in_list": [
    "user@example.com"
  ],
  "not_in_list": [
    "user@example.com"
  ],
  "not_found": [
    "user@example.com"
  ],
  "invalid_emails": [
    "string"
  ]
}

DirectUploadCreateRequest

object
purposestringimportimagemedia_asset

Set to import for CSV contact imports, or image/media_asset for image media assets.

blobobjectrequired
Show child attributes
filenamestringrequired
byte_sizeintegerrequired
checksumstringrequired

Base64-encoded MD5 checksum for Active Storage direct upload.

content_typestring
metadataobject
Example
{
  "purpose": "import",
  "blob": {
    "filename": "contacts.csv",
    "byte_size": 1048576,
    "checksum": "string",
    "content_type": "text/csv",
    "metadata": {}
  }
}

DirectUpload

object
signed_idstring

Submit this value to endpoints that consume direct uploads.

filenamestring
byte_sizeinteger
content_typestring | null
direct_uploadobject
Show child attributes
urlstring<uri>
headersobject
Example
{
  "signed_id": "string",
  "filename": "string",
  "byte_size": 0,
  "content_type": "string",
  "direct_upload": {
    "url": "https://example.com",
    "headers": {}
  }
}

ImportPolicy

object

Import limits for the authenticated account, derived from its deliverability standing. Clients render these values and never recompute them.

standingstringrequired

The account standing the limits derive from.

max_rowsinteger | nullrequired

Row ceiling for one import. Null means no row ceiling for this standing.

max_file_size_bytesintegerrequired
max_file_size_mbintegerrequired
max_active_importsintegerrequired
create_rate_limit_per_minuteintegerrequired
direct_upload_rate_limit_per_minuteintegerrequired
write_modesArray<string>realshadowdry_runrequired
Example
{
  "standing": "trusted",
  "max_rows": null,
  "max_file_size_bytes": 2147483648,
  "max_file_size_mb": 2048,
  "max_active_imports": 10,
  "create_rate_limit_per_minute": 10,
  "direct_upload_rate_limit_per_minute": 30,
  "write_modes": [
    "real"
  ]
}

ImportSpec

object
resourcestringcontactsrequired
parserstringdefaultrequired
uiobject
required_rulesobject
fieldsArray<object>required
guardrailsImportPolicyrequired

Import limits for the authenticated account, derived from its deliverability standing. Clients render these values and never recompute them.

Show child attributes
standingstringrequired

The account standing the limits derive from.

max_rowsinteger | nullrequired

Row ceiling for one import. Null means no row ceiling for this standing.

max_file_size_bytesintegerrequired
max_file_size_mbintegerrequired
max_active_importsintegerrequired
create_rate_limit_per_minuteintegerrequired
direct_upload_rate_limit_per_minuteintegerrequired
write_modesArray<string>realshadowdry_runrequired
Example
{
  "resource": "contacts",
  "parser": "default",
  "ui": {},
  "required_rules": {},
  "fields": [
    {}
  ],
  "guardrails": {
    "standing": "trusted",
    "max_rows": null,
    "max_file_size_bytes": 2147483648,
    "max_file_size_mb": 2048,
    "max_active_imports": 10,
    "create_rate_limit_per_minute": 10,
    "direct_upload_rate_limit_per_minute": 30,
    "write_modes": [
      "real"
    ]
  }
}

ImportGuardrail

object

How this import stands against the account's standing row limit.

tierstringautocontact_usrequired

auto when the row count is within the standing limit; contact_us when it is above it and the import halted.

statusstringokcontact_salesrequired

Client-facing guardrail status vocabulary.

standingstringrequired

The account standing the limit derives from.

max_rowsinteger | nullrequired

Row ceiling for the standing. Null means no row ceiling.

Example
{
  "tier": "auto",
  "status": "ok",
  "standing": "probation",
  "max_rows": 250000
}

Import

object
idinteger
resourcestringcontacts
parserstringdefault
statusstringpendingprocessingfailedcanceledcompletecontact_us
total_rowsinteger | null
success_rowsinteger | null
failed_rowsinteger | null
warning_rowsinteger

Rows imported after one or more unusable optional channels were skipped.

progressobject

Canonical live-progress block (the single progress representation). pct is the only percent source; a null pct means indeterminate.

Show child attributes
statusstringpendingrunningcompletefailed
pctnumber | null
stagesArray<object>
Show child attributes
keystring
labelstring
countinteger
statestringdoneactivependingfailed
import_errorsArray<Array<integer | string>>

Row-level errors as [line_number, message, source].

import_warningsArray<Array<integer | string>>

Bounded row-level warning samples as [line_number, message, reason].

columnsobject | null
optionsobject | null
assigned_list_idsArray<integer>
assigned_listsArray<object>
Show child attributes
idinteger
namestring
guardrailImportGuardrail

How this import stands against the account's standing row limit.

Show child attributes
tierstringautocontact_usrequired

auto when the row count is within the standing limit; contact_us when it is above it and the import halted.

statusstringokcontact_salesrequired

Client-facing guardrail status vocabulary.

standingstringrequired

The account standing the limit derives from.

max_rowsinteger | nullrequired

Row ceiling for the standing. Null means no row ceiling.

started_atstring<date-time> | null
ended_atstring<date-time> | null
created_atstring<date-time>
Example
{
  "id": 0,
  "resource": "contacts",
  "parser": "default",
  "status": "pending",
  "total_rows": 0,
  "success_rows": 0,
  "failed_rows": 0,
  "warning_rows": 0,
  "progress": {
    "status": "pending",
    "pct": 0,
    "stages": [
      {
        "key": "string",
        "label": "string",
        "count": 0,
        "state": "done"
      }
    ]
  },
  "import_errors": [
    [
      0
    ]
  ],
  "import_warnings": [
    [
      0
    ]
  ],
  "columns": {},
  "options": {},
  "assigned_list_ids": [
    0
  ],
  "assigned_lists": [
    {
      "id": 0,
      "name": "string"
    }
  ],
  "guardrail": {
    "tier": "auto",
    "status": "ok",
    "standing": "probation",
    "max_rows": 250000
  },
  "started_at": "2024-01-15T09:30:00Z",
  "ended_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}

Export

object
idinteger
resourcestringcontacts
formatstringcsv
statusstringpendingprocessingcompletefailed
total_rowsinteger | null
rows_writteninteger

Rows written so far; the live numerator against total_rows.

error_messagestring | null
readyboolean

True once the export is complete and the file is available.

download_pathstring | null

Path to download the CSV; present only when ready is true.

progressobject

Live job-progress block, updated as the export streams. status normalizes the job lifecycle, pct is the completion percentage (null while the row count is still unknown), and stages is the ordered Queued to Building to Ready funnel.

Show child attributes
statusstringpendingrunningcompletefailed
pctnumber | null

Completion percentage, or null when indeterminate.

stagesArray<object>
Show child attributes
keystring
labelstring
countinteger | null
statestringdoneactivependingfailed
started_atstring<date-time> | null
ended_atstring<date-time> | null
created_atstring<date-time>
Example
{
  "id": 0,
  "resource": "contacts",
  "format": "csv",
  "status": "pending",
  "total_rows": 0,
  "rows_written": 0,
  "error_message": "string",
  "ready": true,
  "download_path": "string",
  "progress": {
    "status": "pending",
    "pct": 0,
    "stages": [
      {
        "key": "string",
        "label": "string",
        "count": 0,
        "state": "done"
      }
    ]
  },
  "started_at": "2024-01-15T09:30:00Z",
  "ended_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}

SavedView

object
idinteger
surfacestringcontactssendingactivity
namestring
visibilitystringprivateshared
filtersSegmentFilterExpression
layoutSavedViewLayout | null

Table layout preset for contacts surface views. Only present when surface = contacts.

Show child attributes
columnsArray<string>

Ordered list of column keys to display

sortobject
Show child attributes
fieldstring

Column key to sort by

dirstringascdesc

Sort direction

ownerboolean

True when the current user is the creator of this view

created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "surface": "contacts",
  "name": "string",
  "visibility": "private",
  "layout": {
    "columns": [
      "string"
    ],
    "sort": {
      "field": "string",
      "dir": "asc"
    }
  },
  "owner": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

SavedViewLayout

object

Table layout preset for contacts surface views. Only present when surface = contacts.

columnsArray<string>

Ordered list of column keys to display

sortobject
Show child attributes
fieldstring

Column key to sort by

dirstringascdesc

Sort direction

Example
{
  "columns": [
    "string"
  ],
  "sort": {
    "field": "string",
    "dir": "asc"
  }
}

Segment

object
idinteger
account_idinteger
brand_idinteger | null
namestring
originstringusersystem

Who owns this segment. user (default) — created and managed by the user; system — curated by the platform (Champions, Loyal, At-Risk, Dormant, New, Suppressed, Recently unsubscribed, Bounced). System segments cannot be renamed or deleted via the API.

filtersSegmentFilterExpression
cached_countinteger | null

Last asynchronously refreshed contact count for this segment.

count_computed_atstring<date-time> | null

When cached_count was last refreshed.

created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "name": "string",
  "origin": "user",
  "cached_count": 0,
  "count_computed_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

SegmentFilterExpression

object

Request-side audience filter grammar. Use a flat array for ordinary AND filters, { "operator": "and", "children": [...] } for the legacy expression wrapper, or { "op": "and"|"or"|"not", "conditions": [...] } for nested boolean logic. NOT groups must contain exactly one condition.

One of
Array<AttributeSegmentFilter | any | any>
operatorstringandrequired
notbooleanfalsefalse

Legacy flat-AND wrapper does not carry NOT; use BooleanSegmentFilterGroup for NOT.

childrenArray<AttributeSegmentFilter | any | any>required

Segment filters are validated fail-closed. Unknown filter names, globally invalid predicates, type-incompatible predicates, bad date values, invalid enum values, and unsupported rolling-window filters return a 422 invalid_filter error instead of silently widening an audience.

Show child attributes
One of
namestringrequired

Filter name from nitro://schema: contact_first_name, contact_last_name, contact_phone_number, contact_email, contact_country, contact_subscribed_phone, contact_subscribed_email, contact_created_at, contact_last_interacted_at, contact_source, contact_tag, contact_engagement_rating, contact_emails_sent, contact_last_opened_at, contact_last_clicked_at, contact_unique_opens, contact_clicks, contact_open_rate, contact_click_rate, contact_suppressed, contact_suppression_reason, contact_bounced, contact_complained, contact_soft_bounce_count, contact_unsubscribed_at, contact_list. Catalogued custom and enrichment fields are exposed as contact_data_, with dots replaced by underscores (for example, data.attio.lifecycle_stage becomes contact_data_attio_lifecycle_stage).

predicatestringrequired

Ransack predicate: eq, not_eq, cont, not_cont, start, end, gt, lt, gteq, lteq, present, blank, true, false, in, not_in, within_days, not_within_days. Read /v1/my/flows/spec or nitro://schema for the predicates allowed by each filter type.

valueanyrequired

Filter value — string, number, boolean, array of strings for in/not_in predicates (e.g. ["engaged","warm"] for contact_engagement_rating in), or array of list ids for contact_list.

One of
predicatestringperformednot_performedrequired
predicatestringcount_at_leastcount_at_mostrequired
BooleanSegmentFilterGroup
Example
[
  {
    "name": "string",
    "predicate": "string"
  }
]

FlatAndSegmentFilterExpression

object
operatorstringandrequired
notbooleanfalsefalse

Legacy flat-AND wrapper does not carry NOT; use BooleanSegmentFilterGroup for NOT.

childrenArray<AttributeSegmentFilter | any | any>required

Segment filters are validated fail-closed. Unknown filter names, globally invalid predicates, type-incompatible predicates, bad date values, invalid enum values, and unsupported rolling-window filters return a 422 invalid_filter error instead of silently widening an audience.

Show child attributes
One of
namestringrequired

Filter name from nitro://schema: contact_first_name, contact_last_name, contact_phone_number, contact_email, contact_country, contact_subscribed_phone, contact_subscribed_email, contact_created_at, contact_last_interacted_at, contact_source, contact_tag, contact_engagement_rating, contact_emails_sent, contact_last_opened_at, contact_last_clicked_at, contact_unique_opens, contact_clicks, contact_open_rate, contact_click_rate, contact_suppressed, contact_suppression_reason, contact_bounced, contact_complained, contact_soft_bounce_count, contact_unsubscribed_at, contact_list. Catalogued custom and enrichment fields are exposed as contact_data_, with dots replaced by underscores (for example, data.attio.lifecycle_stage becomes contact_data_attio_lifecycle_stage).

predicatestringrequired

Ransack predicate: eq, not_eq, cont, not_cont, start, end, gt, lt, gteq, lteq, present, blank, true, false, in, not_in, within_days, not_within_days. Read /v1/my/flows/spec or nitro://schema for the predicates allowed by each filter type.

valueanyrequired

Filter value — string, number, boolean, array of strings for in/not_in predicates (e.g. ["engaged","warm"] for contact_engagement_rating in), or array of list ids for contact_list.

One of
predicatestringperformednot_performedrequired
predicatestringcount_at_leastcount_at_mostrequired
Example
{
  "operator": "and",
  "not": false,
  "children": [
    {
      "name": "string",
      "predicate": "string"
    }
  ]
}

SegmentFilterNode

object
One of
namestringrequired

Filter name from nitro://schema: contact_first_name, contact_last_name, contact_phone_number, contact_email, contact_country, contact_subscribed_phone, contact_subscribed_email, contact_created_at, contact_last_interacted_at, contact_source, contact_tag, contact_engagement_rating, contact_emails_sent, contact_last_opened_at, contact_last_clicked_at, contact_unique_opens, contact_clicks, contact_open_rate, contact_click_rate, contact_suppressed, contact_suppression_reason, contact_bounced, contact_complained, contact_soft_bounce_count, contact_unsubscribed_at, contact_list. Catalogued custom and enrichment fields are exposed as contact_data_, with dots replaced by underscores (for example, data.attio.lifecycle_stage becomes contact_data_attio_lifecycle_stage).

predicatestringrequired

Ransack predicate: eq, not_eq, cont, not_cont, start, end, gt, lt, gteq, lteq, present, blank, true, false, in, not_in, within_days, not_within_days. Read /v1/my/flows/spec or nitro://schema for the predicates allowed by each filter type.

valueanyrequired

Filter value — string, number, boolean, array of strings for in/not_in predicates (e.g. ["engaged","warm"] for contact_engagement_rating in), or array of list ids for contact_list.

One of
predicatestringperformednot_performedrequired
predicatestringcount_at_leastcount_at_mostrequired
BooleanSegmentFilterGroup
Example
{
  "name": "string",
  "predicate": "string"
}

BooleanSegmentFilterGroup

object
opstringandornotrequired
conditionsArray<any>required

Nested filter nodes. NOT groups must contain exactly one condition.

Example
{
  "op": "and",
  "conditions": []
}

SegmentFilters

array

Segment filters are validated fail-closed. Unknown filter names, globally invalid predicates, type-incompatible predicates, bad date values, invalid enum values, and unsupported rolling-window filters return a 422 invalid_filter error instead of silently widening an audience.

Array<AttributeSegmentFilter | any | any>
Example
[
  {
    "name": "string",
    "predicate": "string"
  }
]

SegmentPreview

object
countinteger

Live count of contacts matching the supplied filters.

sampleArray<object>

Bounded contact sample for quick verification.

Show child attributes
idinteger
emailstring | null
namestring | null
overlapArray<object>

Bounded overlap with existing segments.

Show child attributes
segment_idinteger
namestring
overlap_countinteger
Example
{
  "count": 0,
  "sample": [
    {
      "id": 0,
      "email": "string",
      "name": "string"
    }
  ],
  "overlap": [
    {
      "segment_id": 0,
      "name": "string",
      "overlap_count": 0
    }
  ]
}

AttributeSegmentFilter

object
namestringrequired

Filter name from nitro://schema: contact_first_name, contact_last_name, contact_phone_number, contact_email, contact_country, contact_subscribed_phone, contact_subscribed_email, contact_created_at, contact_last_interacted_at, contact_source, contact_tag, contact_engagement_rating, contact_emails_sent, contact_last_opened_at, contact_last_clicked_at, contact_unique_opens, contact_clicks, contact_open_rate, contact_click_rate, contact_suppressed, contact_suppression_reason, contact_bounced, contact_complained, contact_soft_bounce_count, contact_unsubscribed_at, contact_list. Catalogued custom and enrichment fields are exposed as contact_data_, with dots replaced by underscores (for example, data.attio.lifecycle_stage becomes contact_data_attio_lifecycle_stage).

predicatestringrequired

Ransack predicate: eq, not_eq, cont, not_cont, start, end, gt, lt, gteq, lteq, present, blank, true, false, in, not_in, within_days, not_within_days. Read /v1/my/flows/spec or nitro://schema for the predicates allowed by each filter type.

valueanyrequired

Filter value — string, number, boolean, array of strings for in/not_in predicates (e.g. ["engaged","warm"] for contact_engagement_rating in), or array of list ids for contact_list.

Example
{
  "name": "string",
  "predicate": "string"
}

EventSegmentFilter

object
One of
predicatestringperformednot_performedrequired
predicatestringcount_at_leastcount_at_mostrequired
Example
{
  "predicate": "performed"
}

Campaign

object
idinteger
account_idinteger
brand_idinteger | null
statusstringdraftactivepausedcompleted
approval_statestring
draft_revision_idinteger | null
draft_revision_digeststring | null
draft_approval_statestring | nullpending_reviewapprovedrejected
active_revision_idinteger | null
active_revision_digeststring | null
has_unpublished_changesboolean
channelstringemailsms
namestring
dataobject
scheduled_atstring<date-time> | null
sent_countinteger
dashboard_urlstring<uri> | null

Canonical dashboard URL with the /my route prefix.

preview_urlstring<uri> | null

Signed, expiring public preview URL for the current template version.

recipient_snapshotobject | null

Last send snapshot. Values are captured at send time and are not a live audience estimate.

Show child attributes
requested_recipientsinteger | null
dispatched_recipientsinteger | null
blocked_recipientsinteger | null
requested_send_unitsinteger | null
dispatched_send_unitsinteger | null
units_per_recipientinteger | null
send_tokenstring | null
started_atstring<date-time> | null
completed_atstring<date-time> | null
last_send_recipientsinteger | null

Alias for the last dispatched recipient snapshot stored in data.recipients.

deliveryCampaignDeliverySummary | null

Present while a campaign has a current send token; use /delivery to poll, refresh progress, and receive polling metadata.

engagementEngagementBucket & object
revenueRevenueReport

Attributed revenue from the orders ledger. This block is omitted when the brand has no connected Shopify or Stripe revenue source.

Show child attributes
attribution_labelstring
currencystring | null

Dominant attributed order currency used for revenue math. Null when no attributed orders carry a currency.

mixed_currencyboolean

True when attributed orders included more than one currency before dominant-currency filtering.

attributed_revenue_centsinteger

Net attributed revenue in cents from the orders ledger.

deliveredinteger
attributed_ordersinteger
revenue_per_recipientnumber<float> | null

Net attributed revenue in major currency units divided by delivered recipients.

conversion_ratenumber<float> | null

Attributed paid orders divided by delivered recipients.

attributed_aovnumber<float> | null

Net attributed revenue in major currency units divided by attributed paid orders.

message_breakdownArray<RevenueMessageBreakdown>
Show child attributes
message_idinteger
subjectstring | null
sent_atstring<date-time> | null
currencystring | null

Dominant attributed order currency for this message row.

mixed_currencyboolean

True when attributed orders included more than one currency before dominant-currency filtering.

deliveredinteger
attributed_ordersinteger
attributed_revenue_centsinteger

Net attributed revenue in cents from the orders ledger.

revenue_per_recipientnumber<float> | null
conversion_ratenumber<float> | null
attributed_aovnumber<float> | null
editablebooleanread only

True when the campaign's content/audience/template can be edited. False for live, paused, completed, cancelled, archived, and for scheduled campaigns within 5 minutes of their scheduled_at. When false, PUT update accepts only name-only payloads and status transitions (Resume / Cancel); anything else returns 422 campaign_locked. Use POST /duplicate to fork into a new draft.

created_atstring<date-time>
updated_atstring<date-time>
triggerFlowTrigger
Show child attributes
idinteger
flow_idinteger
eventstring
audience_typestring | nulllistssegmentall_contacts

Explicit campaign audience target; null means no audience selected.

segment_idinteger | null
contact_list_idinteger | nulldeprecated

Deprecated — use contact_list_ids

contact_list_idsArray<integer>

Contact list IDs targeted by this trigger

exclude_segment_idsArray<integer>

Segment IDs whose matching contacts are excluded from the recipient set

exclude_contact_list_idsArray<integer>

Contact list IDs whose members are excluded from the recipient set

dataobject | null
triggered_countinteger
last_triggered_atstring<date-time> | null
created_atstring<date-time>
updated_atstring<date-time>
templateTemplate | null
templatesArray<Template>
Show child attributes
idinteger
namestring | null
flow_idinteger | null
action_idinteger | null
versioninteger
subjectstring | null
bodystring | null
preheaderstring | null
from_namestring | null
from_emailstring | null
reply_tostring | null
designEmailDesign | null
variablesobject
generation_provenanceGenerationProvenance

Candidate-bound generation evidence. Save endpoints accept only state: candidate values returned by the generation endpoint. Resource responses may return state: accepted as read-only history.

Show child attributes
statestringcandidateacceptedrequired
event_idintegerrequired
candidate_locatorstring
generated_slice_digeststring
acceptance_idinteger
saved_authored_digeststring
edit_relationstringidenticaledited
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "status": "draft",
  "approval_state": "string",
  "draft_revision_id": 0,
  "draft_revision_digest": "string",
  "draft_approval_state": "pending_review",
  "active_revision_id": 0,
  "active_revision_digest": "string",
  "has_unpublished_changes": true,
  "channel": "email",
  "name": "string",
  "data": {},
  "scheduled_at": "2024-01-15T09:30:00Z",
  "sent_count": 0,
  "dashboard_url": "https://example.com",
  "preview_url": "https://example.com",
  "recipient_snapshot": {
    "requested_recipients": 0,
    "dispatched_recipients": 0,
    "blocked_recipients": 0,
    "requested_send_units": 0,
    "dispatched_send_units": 0,
    "units_per_recipient": 0,
    "send_token": "string",
    "started_at": "2024-01-15T09:30:00Z",
    "completed_at": "2024-01-15T09:30:00Z"
  },
  "last_send_recipients": 0,
  "delivery": {
    "capacity_recovery": {
      "state": "approaching",
      "reason_code": "sending_capacity_warning",
      "blocking_control": "commercial_capacity",
      "usage_percent": 0,
      "requested_quantity": 0,
      "label": "string",
      "detail": "string",
      "capacity": {
        "source": "plan",
        "window_seconds": 86400,
        "status": "known",
        "limit": 0,
        "reserved": 0,
        "accepted": 0,
        "provider_unknown": 0,
        "remaining": 0
      },
      "upgrade_url": "https://example.com",
      "retry_at": "2024-01-15T09:30:00Z",
      "recovery_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      },
      "recovery_actions": [
        {
          "type": "upgrade_plan",
          "label": "string",
          "detail": "string",
          "url": "https://example.com",
          "required_role": "account_owner_or_admin"
        }
      ],
      "owner_action": {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    },
    "campaign_send_token": "string",
    "status": "sending",
    "recipients": 0,
    "sent": 0,
    "failed": 0,
    "pending": 0
  },
  "engagement": {
    "sent": 0,
    "opens": 0,
    "total_opens": 0,
    "open_rate": 0,
    "account": {
      "sent": 0,
      "opens": 0,
      "total_opens": 0,
      "open_rate": 0
    }
  },
  "revenue": {
    "attribution_label": "Attributed revenue. Last click, 7-day window.",
    "currency": "string",
    "mixed_currency": true,
    "attributed_revenue_cents": 0,
    "delivered": 0,
    "attributed_orders": 0,
    "revenue_per_recipient": 0,
    "conversion_rate": 0,
    "attributed_aov": 0,
    "message_breakdown": [
      {
        "message_id": 0,
        "subject": "string",
        "sent_at": "2024-01-15T09:30:00Z",
        "currency": "string",
        "mixed_currency": true,
        "delivered": 0,
        "attributed_orders": 0,
        "attributed_revenue_cents": 0,
        "revenue_per_recipient": 0,
        "conversion_rate": 0,
        "attributed_aov": 0
      }
    ]
  },
  "editable": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "trigger": {
    "id": 0,
    "flow_id": 0,
    "event": "string",
    "audience_type": "lists",
    "segment_id": 0,
    "contact_list_id": 0,
    "contact_list_ids": [
      0
    ],
    "exclude_segment_ids": [
      0
    ],
    "exclude_contact_list_ids": [
      0
    ],
    "data": {},
    "triggered_count": 0,
    "last_triggered_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "template": {
    "id": 0,
    "name": "string",
    "flow_id": 0,
    "action_id": 0,
    "version": 0,
    "subject": "string",
    "body": "string",
    "preheader": "string",
    "from_name": "string",
    "from_email": "string",
    "reply_to": "string",
    "design": {
      "version": 1,
      "sections": [
        {
          "type": "header",
          "props": {},
          "styles": {
            "background_color": "string",
            "section_background_color": "string",
            "padding": "string",
            "align": "left",
            "scale": "display",
            "font_size": 0,
            "text_color": "string",
            "shape": "square",
            "remove_gap": true,
            "border_radius": 0
          }
        }
      ],
      "theme": {
        "brand_color": "string",
        "bg_color": "string",
        "text_color": "string",
        "font_body": "string",
        "font_heading": "string",
        "heading_size": 0,
        "body_size": 0,
        "radius": 0,
        "spacing_density": "compact",
        "button_background_color": "string",
        "button_text_color": "string",
        "button_padding": "string",
        "logo_url": "string",
        "company_name": "string",
        "physical_address": "string",
        "social_links": [
          {
            "platform": "string",
            "url": "string"
          }
        ]
      }
    },
    "variables": {},
    "generation_provenance": {
      "state": "candidate",
      "event_id": 0,
      "candidate_locator": "string",
      "generated_slice_digest": "string",
      "acceptance_id": 0,
      "saved_authored_digest": "string",
      "edit_relation": "identical"
    },
    "created_at": "2024-01-15T09:30:00Z",
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "templates": [
    {
      "id": 0,
      "name": "string",
      "flow_id": 0,
      "action_id": 0,
      "version": 0,
      "subject": "string",
      "body": "string",
      "preheader": "string",
      "from_name": "string",
      "from_email": "string",
      "reply_to": "string",
      "design": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      },
      "variables": {},
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      },
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}

CampaignDeliverySummary

object
capacity_recoveryDeliveryCapacityRecovery

Informational recovery at 80 percent used, exhaustion, or when a campaign exceeds remaining allowance. Never denies a send or promises that payment or verification bypasses safety. Actions come from the shared backend projection; only offer verification when new valid proof can improve standing.

Show child attributes
statestringapproachingreachedcampaign_exceeds_remainingrequired
reason_codestringsending_capacity_warningsending_capacity_reachedrequired
blocking_controlstringcommercial_capacityrequired
usage_percentinteger[0, 100]required
requested_quantityinteger>= 0
labelstringrequired
detailstringrequired
capacityDeliveryCapacityrequired
Show child attributes
sourcestringplanoperator_override
window_secondsinteger
statusstringknownunlimitednot_applicableunknowndegradedrequired
limitinteger | null>= 0required
reservedinteger | null>= 0required
acceptedinteger | null>= 0required
provider_unknowninteger | null>= 0required
remaininginteger | null>= 0required
upgrade_urlstring<uri>

Shareable account-specific plan link. Authentication and billing permissions still apply.

retry_atstring<date-time>

Recorded retry time, not a guarantee that delivery completes then.

recovery_actionDeliveryCapacityRecoveryActionrequired
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
recovery_actionsArray<DeliveryCapacityRecoveryAction>required
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
owner_actionDeliveryCapacityRecoveryActionrequired
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
campaign_send_tokenstring | nullrequired
statusstringsendingcompletedpausedrequired
recipientsintegerrequired

Recipient count captured for the active send.

sentintegerrequired
failedintegerrequired
pendingintegerrequired
Example
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "campaign_send_token": "string",
  "status": "sending",
  "recipients": 0,
  "sent": 0,
  "failed": 0,
  "pending": 0
}

CampaignDeliveryProgress

object
capacity_recoveryDeliveryCapacityRecovery

Informational recovery at 80 percent used, exhaustion, or when a campaign exceeds remaining allowance. Never denies a send or promises that payment or verification bypasses safety. Actions come from the shared backend projection; only offer verification when new valid proof can improve standing.

Show child attributes
statestringapproachingreachedcampaign_exceeds_remainingrequired
reason_codestringsending_capacity_warningsending_capacity_reachedrequired
blocking_controlstringcommercial_capacityrequired
usage_percentinteger[0, 100]required
requested_quantityinteger>= 0
labelstringrequired
detailstringrequired
capacityDeliveryCapacityrequired
Show child attributes
sourcestringplanoperator_override
window_secondsinteger
statusstringknownunlimitednot_applicableunknowndegradedrequired
limitinteger | null>= 0required
reservedinteger | null>= 0required
acceptedinteger | null>= 0required
provider_unknowninteger | null>= 0required
remaininginteger | null>= 0required
upgrade_urlstring<uri>

Shareable account-specific plan link. Authentication and billing permissions still apply.

retry_atstring<date-time>

Recorded retry time, not a guarantee that delivery completes then.

recovery_actionDeliveryCapacityRecoveryActionrequired
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
recovery_actionsArray<DeliveryCapacityRecoveryAction>required
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
owner_actionDeliveryCapacityRecoveryActionrequired
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
campaign_send_tokenstring | nullrequired
statusstringnot_startedsendingcompletedpausedrequired
recipientsintegerrequired

Recipient count captured for the active send.

sentintegerrequired
failedintegerrequired
pendingintegerrequired
terminalbooleanrequired

True when clients can stop polling.

poll_after_secondsinteger | nullrequired

Suggested polling delay for active sends.

Example
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "campaign_send_token": "string",
  "status": "not_started",
  "recipients": 0,
  "sent": 0,
  "failed": 0,
  "pending": 0,
  "terminal": true,
  "poll_after_seconds": 0
}

MailActionDescription

object

A Mail Action Protocol 0.2 description. The canonical MailSchema core schema is authoritative; this schema restates its shape.

@contextstringhttps://mailschema.org/contexts/map-0.2.jsonldrequired
@typestringMailActionrequired
@idstring<uri>required

UUID URN identifying the interaction.

profilestringhttps://mailschema.org/profiles/map/0.2required
typeMailActionTypeReferencerequired
Show child attributes
idstring<uri>required
versionstringrequired
contractDigeststringrequired
describedAtstring<date-time>required
expiresAtstring<date-time>required
serviceMailActionServicerequired
Show child attributes
idstring<uri>required
namestringrequired
authoritystringcredentialpossessionrequired
resourcestring<uri>

The RFC 9728 protected resource identifier. Present exactly with credential authority.

executionobjectrequired
Show child attributes
urlstring<uri>required
resultUrlTemplatestringrequired
resultRetentionSecondsinteger[300, 31536000]required
humanUrlstring<uri>required
recipientstring<email>

The address a possession capability was issued to. Present exactly with possession authority.

targetMailActionTargetrequired
Show child attributes
idstring<uri>required
revisionstringrequired
titlestring
digeststringrequired
detailsobject

Defined by the type contract. Content Review 0.3 names the revision this one supersedes.

operationsArray<MailActionOperation>required
Show child attributes
idstringrequired
namestringrequired
descriptionstringrequired
Example
{
  "@context": "https://mailschema.org/contexts/map-0.2.jsonld",
  "@type": "MailAction",
  "@id": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  },
  "describedAt": "2024-01-15T09:30:00Z",
  "expiresAt": "2024-01-15T09:30:00Z",
  "service": {
    "id": "https://example.com",
    "name": "string",
    "authority": "credential",
    "resource": "https://example.com",
    "execution": {
      "url": "https://example.com",
      "resultUrlTemplate": "string",
      "resultRetentionSeconds": 300
    },
    "humanUrl": "https://example.com"
  },
  "recipient": "user@example.com",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "details": {},
  "operations": [
    {
      "id": "string",
      "name": "string",
      "description": "string"
    }
  ]
}

MailActionTypeReference

object
idstring<uri>required
versionstringrequired
contractDigeststringrequired
Example
{
  "id": "https://example.com",
  "version": "string",
  "contractDigest": "string"
}

MailActionTarget

object
idstring<uri>required
revisionstringrequired
titlestring
digeststringrequired
Example
{
  "id": "https://example.com",
  "revision": "string",
  "title": "string",
  "digest": "string"
}

MailActionOperation

object
idstringrequired
namestringrequired
descriptionstringrequired
Example
{
  "id": "string",
  "name": "string",
  "description": "string"
}

MailActionService

object
idstring<uri>required
namestringrequired
authoritystringcredentialpossessionrequired
resourcestring<uri>

The RFC 9728 protected resource identifier. Present exactly with credential authority.

executionobjectrequired
Show child attributes
urlstring<uri>required
resultUrlTemplatestringrequired
resultRetentionSecondsinteger[300, 31536000]required
humanUrlstring<uri>required
Example
{
  "id": "https://example.com",
  "name": "string",
  "authority": "credential",
  "resource": "https://example.com",
  "execution": {
    "url": "https://example.com",
    "resultUrlTemplate": "string",
    "resultRetentionSeconds": 300
  },
  "humanUrl": "https://example.com"
}

MailActionRequest

object

A MAP 0.2 Content Review request. Its operation decides its input.

One of
kindstringrequired
profilestringrequired
requestIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

interactionIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

descriptionDigeststringrequired

SHA-256 over the RFC 8785 canonical form of the description exactly as the email carried it.

typeMailActionTypeReferencerequired
Show child attributes
idstring<uri>required
versionstringrequired
contractDigeststringrequired
kindstringrequired
profilestringrequired
requestIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

interactionIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

descriptionDigeststringrequired

SHA-256 over the RFC 8785 canonical form of the description exactly as the email carried it.

typeMailActionTypeReferencerequired
Show child attributes
idstring<uri>required
versionstringrequired
contractDigeststringrequired
Example
{
  "kind": "MapRequest",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "descriptionDigest": "string",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  }
}

MailActionRequestEnvelope

object
kindstringrequired
profilestringrequired
requestIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

interactionIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

descriptionDigeststringrequired

SHA-256 over the RFC 8785 canonical form of the description exactly as the email carried it.

typeMailActionTypeReferencerequired
Show child attributes
idstring<uri>required
versionstringrequired
contractDigeststringrequired
Example
{
  "kind": "MapRequest",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "descriptionDigest": "string",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  }
}

MailActionRequestChanges

object
kindstringrequired
profilestringrequired
requestIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

interactionIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

descriptionDigeststringrequired

SHA-256 over the RFC 8785 canonical form of the description exactly as the email carried it.

typeMailActionTypeReferencerequired
Show child attributes
idstring<uri>required
versionstringrequired
contractDigeststringrequired
Example
{
  "kind": "MapRequest",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "descriptionDigest": "string",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  }
}

MailActionApprove

object
kindstringrequired
profilestringrequired
requestIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

interactionIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

descriptionDigeststringrequired

SHA-256 over the RFC 8785 canonical form of the description exactly as the email carried it.

typeMailActionTypeReferencerequired
Show child attributes
idstring<uri>required
versionstringrequired
contractDigeststringrequired
Example
{
  "kind": "MapRequest",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "descriptionDigest": "string",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  }
}

MailActionUuidUrn

string

A UUID URN, as the MAP 0.2 core defines it.

MailActionUuidUrn
Example
"string"

MailActionRequestChangesInput

object

The input of request-changes.

feedbackstringrequired

Review feedback on the revision; it must contain a character that is not a space.

Example
{
  "feedback": "string"
}

MailActionApproveInput

object

The input of approve, which is always empty.

MailActionApproveInput
Example
{}

MailActionResult

object
kindstringrequired
profilestringrequired
requestIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

interactionIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

descriptionDigeststringrequired
typeMailActionTypeReferencerequired
Show child attributes
idstring<uri>required
versionstringrequired
contractDigeststringrequired
operationstringrequest-changesapproverequired
statestringacceptedcompletedfailedpendingapproval-requiredrequired
targetMailActionTargetrequired
Show child attributes
idstring<uri>required
revisionstringrequired
titlestring
digeststringrequired
recordedAtstring<date-time>required
resultUrlstring<uri>required
approvalUrlstring<uri>

Present exactly when the state is approval-required. A person decides there.

reasonstringdeclinedstale-targetexpiredsuperseded

Present exactly when the state is failed.

outputobjectrequired

request-changes: feedbackRecorded and a service-issued feedbackId. approve: decision approved when completed; empty otherwise.

Example
{
  "kind": "MapResult",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "descriptionDigest": "string",
  "type": {
    "id": "https://example.com",
    "version": "string",
    "contractDigest": "string"
  },
  "operation": "request-changes",
  "state": "accepted",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "recordedAt": "2024-01-15T09:30:00Z",
  "resultUrl": "https://example.com",
  "approvalUrl": "https://example.com",
  "reason": "declined",
  "output": {}
}

MailActionProtectedResource

object

RFC 9728 protected resource metadata with the MAP map_services parameter.

resourcestring<uri>required
resource_namestring
bearer_methods_supportedArray<string>headerrequired
map_servicesArray<object>required
Show child attributes
idstring<uri>required
profilesArray<string>required
execution_urlstring<uri>required
result_url_templatestringrequired
Example
{
  "resource": "https://example.com",
  "resource_name": "string",
  "bearer_methods_supported": [
    "header"
  ],
  "map_services": [
    {
      "id": "https://example.com",
      "profiles": [
        "https://example.com"
      ],
      "execution_url": "https://example.com",
      "result_url_template": "string"
    }
  ]
}

MailActionProblem

object
typestring<uri>required
titlestringrequired
statusinteger[400, 599]required
detailstringrequired
instancestring<uri>required
profilestringrequired
requestIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

interactionIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

codestringinvalid-requestrefusedresult-not-foundstale-targetidempotency-conflictrequest-in-progressalready-decidedexpired-interactionunsupported-typeunsupported-operationrequired
targetMailActionTarget

For stale-target, the target the service now holds.

Show child attributes
idstring<uri>required
revisionstringrequired
titlestring
digeststringrequired
errorsArray<object>

For invalid-request input, each problem with a JSON Pointer into the request input.

Show child attributes
detailstringrequired
pointerstringrequired
Example
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "interactionId": "string",
  "code": "invalid-request",
  "target": {
    "id": "https://example.com",
    "revision": "string",
    "title": "string",
    "digest": "string"
  },
  "errors": [
    {
      "detail": "string",
      "pointer": "string"
    }
  ]
}

MailActionResultNotFoundProblem

object

Correlated MAP result lookup failure. No interaction identifier is invented when no retained result exists.

typestringrequired
titlestringrequired
statusintegerrequired
detailstringrequired
instancestring<uri>required
profilestringrequired
requestIdMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

codestringrequired
Example
{
  "type": "https://mailschema.org/problems/result-not-found",
  "title": "string",
  "status": 404,
  "detail": "string",
  "instance": "https://example.com",
  "profile": "https://mailschema.org/profiles/map/0.2",
  "requestId": "string",
  "code": "result-not-found"
}

MailActionApproval

object
request_idMailActionUuidUrnrequired

A UUID URN, as the MAP 0.2 core defines it.

statestringapproval-requiredcompletedfailedrequired
requested_atstring<date-time>required
flowobjectrequired
Show child attributes
idintegerrequired
namestringrequired
revisionrevisionrequired
Show child attributes
idintegerrequired
digeststringrequired
approval_statestringpending_reviewapprovedrejectedrequired
currentbooleanrequired
triggerobjectrequired
Show child attributes
eventstringrequired
stepsArray<object>required
Show child attributes
namestringrequired
typestringrequired
waitinteger | null
subjectstring | null
preheaderstring | null
from_namestring | null
from_emailstring | null
htmlstring | null
resultMailActionResult | MailActionProblemrequired
Example
{
  "request_id": "string",
  "state": "approval-required",
  "requested_at": "2024-01-15T09:30:00Z",
  "flow": {
    "id": 0,
    "name": "string"
  },
  "revision": {
    "id": 0,
    "digest": "string",
    "approval_state": "pending_review",
    "current": true,
    "trigger": {
      "event": "string"
    },
    "steps": [
      {
        "name": "string",
        "type": "string",
        "wait": 0,
        "subject": "string",
        "preheader": "string",
        "from_name": "string",
        "from_email": "string",
        "html": "string"
      }
    ]
  },
  "result": {
    "kind": "MapResult",
    "profile": "https://mailschema.org/profiles/map/0.2",
    "requestId": "string",
    "interactionId": "string",
    "descriptionDigest": "string",
    "type": {
      "id": "https://example.com",
      "version": "string",
      "contractDigest": "string"
    },
    "operation": "request-changes",
    "state": "accepted",
    "target": {
      "id": "https://example.com",
      "revision": "string",
      "title": "string",
      "digest": "string"
    },
    "recordedAt": "2024-01-15T09:30:00Z",
    "resultUrl": "https://example.com",
    "approvalUrl": "https://example.com",
    "reason": "declined",
    "output": {}
  }
}

MailActionRevisionReview

object
statestringapproval-requiredcompletedfailedrequired
flowobjectrequired
Show child attributes
idintegerrequired
namestringrequired
revisionrevisionrequired
Show child attributes
idintegerrequired
digeststringrequired
approval_statestringpending_reviewapprovedrejectedrequired
currentbooleanrequired
triggerobjectrequired
Show child attributes
eventstringrequired
stepsArray<object>required
Show child attributes
namestringrequired
typestringrequired
waitinteger | null
subjectstring | null
preheaderstring | null
from_namestring | null
from_emailstring | null
htmlstring | null
Example
{
  "state": "approval-required",
  "flow": {
    "id": 0,
    "name": "string"
  },
  "revision": {
    "id": 0,
    "digest": "string",
    "approval_state": "pending_review",
    "current": true,
    "trigger": {
      "event": "string"
    },
    "steps": [
      {
        "name": "string",
        "type": "string",
        "wait": 0,
        "subject": "string",
        "preheader": "string",
        "from_name": "string",
        "from_email": "string",
        "html": "string"
      }
    ]
  }
}

HttpProblem

object

Plain RFC 9457 Problem Details for an HTTP answer that is not about a MAP request, made before the body or credential is read.

typestringabout:blankrequired
titlestringrequired
statusinteger[400, 599]required
Example
{
  "type": "about:blank",
  "title": "string",
  "status": 400
}

MailActionUncorrelatedProblem

object

Ordinary RFC 9457 Problem Details for a MAP failure whose request and interaction identifiers could not be recovered.

typestring<uri>required
titlestringrequired
statusinteger[400, 599]required
detailstringrequired
Example
{
  "type": "https://example.com",
  "title": "string",
  "status": 400,
  "detail": "string"
}

Message

object
idinteger
channelstringemailsms
tostring
subjectstring | null
statusstringqueuedsentfailed
provider_idstring | null
flow_idinteger | null

Source flow ID (null for transactional)

source_typestring | nullcampaignflowtest

campaign, flow, test, or null (transactional)

source_namestring | null

Name of source campaign or flow

status_reason_codestring | null

Stable machine-readable reason for a queued or failed message status.

status_reasonstring | null

Human-readable explanation for a queued or failed message status.

status_reason_categorystring | nullcontent_reviewaccountinternalrecipientproviderrate_limitdelivery

Broad category for status_reason.

failure_codestring | null

Stable machine-readable failure reason; present only when status is failed.

failure_reasonstring | null

Human-readable failure explanation; present only when status is failed.

failure_categorystring | nullcontent_reviewaccountinternalrecipientproviderdelivery

Broad category for failure_reason; present only when status is failed.

sent_atstring<date-time> | null
created_atstring<date-time>
Example
{
  "id": 0,
  "channel": "email",
  "to": "string",
  "subject": "string",
  "status": "queued",
  "provider_id": "string",
  "flow_id": 0,
  "source_type": "campaign",
  "source_name": "string",
  "status_reason_code": "string",
  "status_reason": "string",
  "status_reason_category": "content_review",
  "failure_code": "string",
  "failure_reason": "string",
  "failure_category": "content_review",
  "sent_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}

Suppression

object

Account suppression row with bounded source-event diagnostics.

idinteger
emailstring<email>
reasonstringhard_bouncesoft_bouncecomplaintmanualadmin
scopestringaccount_scoped
activeboolean
contact_idinteger | null
source_providerstring | null
source_event_idstring | null
provider_diagnosticstring | null

Bounded diagnostic text extracted from the provider feedback event, when retained.

bounce_typestring | nullhardsoft
bounce_subtypestring | null
complaint_feedback_typestring | null
event_occurred_atstring<date-time> | null
expires_atstring<date-time> | null
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "email": "user@example.com",
  "reason": "hard_bounce",
  "scope": "account_scoped",
  "active": true,
  "contact_id": 0,
  "source_provider": "string",
  "source_event_id": "string",
  "provider_diagnostic": "string",
  "bounce_type": "hard",
  "bounce_subtype": "string",
  "complaint_feedback_type": "string",
  "event_occurred_at": "2024-01-15T09:30:00Z",
  "expires_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

WebhookEventType

string
WebhookEventTypeemail.sentemail.deliveredemail.bouncedemail.complainedemail.openedemail.clickedemail.failedemail.received
Example
"email.sent"

Webhook

object
idinteger
urlstring<uri>
eventsArray<WebhookEventType>email.sentemail.deliveredemail.bouncedemail.complainedemail.openedemail.clickedemail.failedemail.received
enabledboolean
statusstringactivefailingdisabled

failing while deliveries fail; an endpoint failing for 3 days is turned off.

failing_sincestring<date-time> | null
secretstring

Standard Webhooks signing secret (whsec_...). Masked unless revealed.

last_deliveryobject | null
Show child attributes
idinteger
event_typeWebhookEventTypeemail.sentemail.deliveredemail.bouncedemail.complainedemail.openedemail.clickedemail.failedemail.received
statusstringpendingdeliveredfailed
attemptsinteger
last_response_statusinteger | null
updated_atstring<date-time>
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "url": "https://example.com",
  "events": [
    "email.sent"
  ],
  "enabled": true,
  "status": "active",
  "failing_since": "2024-01-15T09:30:00Z",
  "secret": "string",
  "last_delivery": {
    "id": 0,
    "event_type": "email.sent",
    "status": "pending",
    "attempts": 0,
    "last_response_status": 0,
    "updated_at": "2024-01-15T09:30:00Z"
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

WebhookWriteRequest

object
urlstring<uri>

HTTPS URL that resolves only to public addresses, without credentials.

eventsArray<WebhookEventType>email.sentemail.deliveredemail.bouncedemail.complainedemail.openedemail.clickedemail.failedemail.received
enabledboolean
Example
{
  "url": "https://example.com",
  "events": [
    "email.sent"
  ],
  "enabled": true
}

WebhookDelivery

object
idinteger
event_idstring<uuid>

Sent as webhook-id (evt_<event_id>), stable across retries.

event_typeWebhookEventTypeemail.sentemail.deliveredemail.bouncedemail.complainedemail.openedemail.clickedemail.failedemail.received
statusstringpendingdeliveredfailed
attemptsinteger
last_response_statusinteger | null
last_errorstring | null
next_attempt_atstring<date-time>
payloadWebhookEventPayload
Show child attributes
typeWebhookEventTypeemail.sentemail.deliveredemail.bouncedemail.complainedemail.openedemail.clickedemail.failedemail.receivedrequired
timestampstring<date-time>required
dataobjectrequired
Show child attributes
message_idinteger | null

The id POST /v1/my/messages returned. Null on test events.

tostring
subjectstring | null
idempotency_keystring | null

The caller's Idempotency-Key, when one was sent.

tagsobject

The caller's delivery-option tags.

testboolean

Present and true on test events.

sent_atstring<date-time>

email.sent

bounceobject

email.bounced

Show child attributes
typestringhardsoft
subtypestring | null

The provider's bounce subtype, e.g. NoEmail or MailboxFull.

complaintobject

email.complained

Show child attributes
feedback_typestring | null

e.g. abuse

urlstring

email.clicked

failureobject

email.failed

Show child attributes
codestring
reasonstring
categorystring
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "event_id": "550e8400-e29b-41d4-a716-446655440000",
  "event_type": "email.sent",
  "status": "pending",
  "attempts": 0,
  "last_response_status": 0,
  "last_error": "string",
  "next_attempt_at": "2024-01-15T09:30:00Z",
  "payload": {
    "type": "email.sent",
    "timestamp": "2024-01-15T09:30:00Z",
    "data": {
      "message_id": 0,
      "to": "string",
      "subject": "string",
      "idempotency_key": "string",
      "tags": {},
      "test": true,
      "sent_at": "2024-01-15T09:30:00Z",
      "bounce": {
        "type": "hard",
        "subtype": "string"
      },
      "complaint": {
        "feedback_type": "string"
      },
      "url": "string",
      "failure": {
        "code": "string",
        "reason": "string",
        "category": "string"
      }
    }
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

WebhookEventPayload

object
typeWebhookEventTypeemail.sentemail.deliveredemail.bouncedemail.complainedemail.openedemail.clickedemail.failedemail.receivedrequired
timestampstring<date-time>required
dataobjectrequired
Show child attributes
message_idinteger | null

The id POST /v1/my/messages returned. Null on test events.

tostring
subjectstring | null
idempotency_keystring | null

The caller's Idempotency-Key, when one was sent.

tagsobject

The caller's delivery-option tags.

testboolean

Present and true on test events.

sent_atstring<date-time>

email.sent

bounceobject

email.bounced

Show child attributes
typestringhardsoft
subtypestring | null

The provider's bounce subtype, e.g. NoEmail or MailboxFull.

complaintobject

email.complained

Show child attributes
feedback_typestring | null

e.g. abuse

urlstring

email.clicked

failureobject

email.failed

Show child attributes
codestring
reasonstring
categorystring
Example
{
  "type": "email.sent",
  "timestamp": "2024-01-15T09:30:00Z",
  "data": {
    "message_id": 0,
    "to": "string",
    "subject": "string",
    "idempotency_key": "string",
    "tags": {},
    "test": true,
    "sent_at": "2024-01-15T09:30:00Z",
    "bounce": {
      "type": "hard",
      "subtype": "string"
    },
    "complaint": {
      "feedback_type": "string"
    },
    "url": "string",
    "failure": {
      "code": "string",
      "reason": "string",
      "category": "string"
    }
  }
}

WebhookReceivedEventPayload

object
typestringemail.receivedrequired
timestampstring<date-time>required

When the message arrived.

dataobjectrequired
Show child attributes
message_idinteger | null

The send this message answers, as POST /v1/my/messages returned it. Null when it answers none, and on test events.

idempotency_keystring | null

The answered send's Idempotency-Key, when the caller sent one.

tagsobject

The answered send's delivery-option tags; empty when it answers none.

fromstring
tostring

The inbox address it was sent to.

subjectstring | null
textstring | null

Plain-text body

htmlstring | null

HTML body

truncatedboolean

True when either body was cut to 64 KiB.

auto_submittedboolean

True for automatic replies such as out-of-office notices.

attachmentsArray<object>
Show child attributes
idinteger
filenamestring
content_typestring
sizeinteger

Bytes.

scannedboolean

False when no virus scan covered the file; download it with acknowledge_unscanned=true.

conversation_idinteger | null

For GET /v1/my/conversations/{id}. Null on test events.

conversation_message_idinteger | null

Null on test events.

testboolean

Present and true on test events.

Example
{
  "type": "email.received",
  "timestamp": "2024-01-15T09:30:00Z",
  "data": {
    "message_id": 0,
    "idempotency_key": "string",
    "tags": {},
    "from": "string",
    "to": "string",
    "subject": "string",
    "text": "string",
    "html": "string",
    "truncated": true,
    "auto_submitted": true,
    "attachments": [
      {
        "id": 0,
        "filename": "string",
        "content_type": "string",
        "size": 0,
        "scanned": true
      }
    ],
    "conversation_id": 0,
    "conversation_message_id": 0,
    "test": true
  }
}

ChatMessage

object
idinteger
rolestringuserassistanttoolsystem
contentstring

Credential-shaped values are redacted before display.

tool_callsArray<object>
Show child attributes
idstring
namestring
inputobject
safeboolean
statusstringpendingapprovedexecutingcompletedrejectederrorcancelleduncertain
approval_tokenstring

Binds a proposal to its execution and exact arguments. Commands also require the originating authenticated user.

resultany

Recorded tool outcome; queued does not mean sent.

actionsArray<object>
sequenceinteger
created_atstring<date-time>
Example
{
  "id": 0,
  "role": "user",
  "content": "string",
  "tool_calls": [
    {
      "id": "string",
      "name": "string",
      "input": {},
      "safe": true,
      "status": "pending",
      "approval_token": "string"
    }
  ],
  "actions": [
    {}
  ],
  "sequence": 0,
  "created_at": "2024-01-15T09:30:00Z"
}

ChatSession

object
idinteger
account_idinteger
brand_idinteger
titlestring
statusstringactiveclosedfailed
started_atstring<date-time>
last_message_atstring<date-time>
message_countinteger
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "title": "string",
  "status": "active",
  "started_at": "2024-01-15T09:30:00Z",
  "last_message_at": "2024-01-15T09:30:00Z",
  "message_count": 0,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

ChatSessionDetail

object
idinteger
account_idinteger
brand_idinteger
titlestring
statusstringactiveclosedfailed
started_atstring<date-time>
last_message_atstring<date-time>
message_countinteger
created_atstring<date-time>
updated_atstring<date-time>
messagesArray<ChatMessage>
Show child attributes
idinteger
rolestringuserassistanttoolsystem
contentstring

Credential-shaped values are redacted before display.

tool_callsArray<object>
Show child attributes
idstring
namestring
inputobject
safeboolean
statusstringpendingapprovedexecutingcompletedrejectederrorcancelleduncertain
approval_tokenstring

Binds a proposal to its execution and exact arguments. Commands also require the originating authenticated user.

resultany

Recorded tool outcome; queued does not mean sent.

actionsArray<object>
sequenceinteger
created_atstring<date-time>
Example
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "title": "string",
  "status": "active",
  "started_at": "2024-01-15T09:30:00Z",
  "last_message_at": "2024-01-15T09:30:00Z",
  "message_count": 0,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "messages": [
    {
      "id": 0,
      "role": "user",
      "content": "string",
      "tool_calls": [
        {
          "id": "string",
          "name": "string",
          "input": {},
          "safe": true,
          "status": "pending",
          "approval_token": "string"
        }
      ],
      "actions": [
        {}
      ],
      "sequence": 0,
      "created_at": "2024-01-15T09:30:00Z"
    }
  ]
}

Template

object
idinteger
namestring | null
flow_idinteger | null
action_idinteger | null
versioninteger
subjectstring | null
bodystring | null
preheaderstring | null
from_namestring | null
from_emailstring | null
reply_tostring | null
designEmailDesign | null
variablesobject
generation_provenanceGenerationProvenance

Candidate-bound generation evidence. Save endpoints accept only state: candidate values returned by the generation endpoint. Resource responses may return state: accepted as read-only history.

Show child attributes
statestringcandidateacceptedrequired
event_idintegerrequired
candidate_locatorstring
generated_slice_digeststring
acceptance_idinteger
saved_authored_digeststring
edit_relationstringidenticaledited
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "name": "string",
  "flow_id": 0,
  "action_id": 0,
  "version": 0,
  "subject": "string",
  "body": "string",
  "preheader": "string",
  "from_name": "string",
  "from_email": "string",
  "reply_to": "string",
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  },
  "variables": {},
  "generation_provenance": {
    "state": "candidate",
    "event_id": 0,
    "candidate_locator": "string",
    "generated_slice_digest": "string",
    "acceptance_id": 0,
    "saved_authored_digest": "string",
    "edit_relation": "identical"
  },
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

GenerationProvenance

object

Candidate-bound generation evidence. Save endpoints accept only state: candidate values returned by the generation endpoint. Resource responses may return state: accepted as read-only history.

statestringcandidateacceptedrequired
event_idintegerrequired
candidate_locatorstring
generated_slice_digeststring
acceptance_idinteger
saved_authored_digeststring
edit_relationstringidenticaledited
Example
{
  "state": "candidate",
  "event_id": 0,
  "candidate_locator": "string",
  "generated_slice_digest": "string",
  "acceptance_id": 0,
  "saved_authored_digest": "string",
  "edit_relation": "identical"
}

EmailLibraryTemplate

object
idstring
namestring
categorystring
tagsArray<string>
descriptionstring
subjectstring

Suggested subject line

preheaderstring

Suggested preheader

designEmailDesign

Email template design document

Show child attributes
versioninteger>= 1
sectionsArray<EmailSection>
Show child attributes
typestringheaderherotextimagebuttoncolumnsproductproductsgallerysocialdividerspacerfooterrequired
propsobject

Section-specific properties (see email component spec)

stylesobject
Show child attributes
background_colorstring
section_background_colorstring
paddingstring
alignstringleftcenterright
scalestringdisplayposter
font_sizeinteger
text_colorstring
shapestringsquareroundedarchcircle
remove_gapboolean
border_radiusinteger
themeobject

Theme overrides merged on top of brand theme

Show child attributes
brand_colorstring
bg_colorstring
text_colorstring
font_bodystring
font_headingstring
heading_sizeinteger
body_sizeinteger
radiusinteger
spacing_densitystringcompactnormalspacious
button_background_colorstring
button_text_colorstring
button_paddingstring
logo_urlstring
company_namestring
physical_addressstring
social_linksArray<object>
Show child attributes
platformstring
urlstring
preview_htmlstring | null
branded_designEmailDesign

Same layout with palette overrides stripped so brand colors apply

branded_preview_htmlstring | null
Example
{
  "id": "string",
  "name": "string",
  "category": "string",
  "tags": [
    "string"
  ],
  "description": "string",
  "subject": "string",
  "preheader": "string",
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  },
  "preview_html": "string",
  "branded_design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  },
  "branded_preview_html": "string"
}

PublicEmailCatalogTemplate

object
idstringrequired
namestringrequired
categorystringrequired
tagsArray<string>required
descriptionstringrequired
subjectstringrequired
preheaderstringrequired
designEmailDesignrequired

Email template design document

Show child attributes
versioninteger>= 1
sectionsArray<EmailSection>
Show child attributes
typestringheaderherotextimagebuttoncolumnsproductproductsgallerysocialdividerspacerfooterrequired
propsobject

Section-specific properties (see email component spec)

stylesobject
Show child attributes
background_colorstring
section_background_colorstring
paddingstring
alignstringleftcenterright
scalestringdisplayposter
font_sizeinteger
text_colorstring
shapestringsquareroundedarchcircle
remove_gapboolean
border_radiusinteger
themeobject

Theme overrides merged on top of brand theme

Show child attributes
brand_colorstring
bg_colorstring
text_colorstring
font_bodystring
font_headingstring
heading_sizeinteger
body_sizeinteger
radiusinteger
spacing_densitystringcompactnormalspacious
button_background_colorstring
button_text_colorstring
button_paddingstring
logo_urlstring
company_namestring
physical_addressstring
social_linksArray<object>
Show child attributes
platformstring
urlstring
Example
{
  "id": "string",
  "name": "string",
  "category": "string",
  "tags": [
    "string"
  ],
  "description": "string",
  "subject": "string",
  "preheader": "string",
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  }
}

TemplateSummary

object
idinteger
namestring | null
versioninteger
preview_htmlstring | null

Rendered preview, present only with ?include_previews=1

subjectstring | null
preheaderstring | null
flow_idinteger | null
section_countinteger
section_typesArray<string>
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "name": "string",
  "version": 0,
  "preview_html": "string",
  "subject": "string",
  "preheader": "string",
  "flow_id": 0,
  "section_count": 0,
  "section_types": [
    "string"
  ],
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

Flow

object
idinteger
account_idinteger
brand_idinteger | null
statusstringdraftlivepausedarchivedcancelled
approval_statestring
namestring
goalstring | null
triggerFlowTriggerOutput

Trigger as returned by Flow::Format.dump

Show child attributes
eventstring
segment_idinteger | null
contact_list_idinteger | null
exclude_segment_idsArray<integer>

Segment IDs whose matching contacts are excluded from the recipient set

dataobject | null
stepsArray<FlowStepOutput>
sent_countinteger
engagementEngagementBucket & object
revenueRevenueReport

Attributed revenue from the orders ledger. This block is omitted when the brand has no connected Shopify or Stripe revenue source.

Show child attributes
attribution_labelstring
currencystring | null

Dominant attributed order currency used for revenue math. Null when no attributed orders carry a currency.

mixed_currencyboolean

True when attributed orders included more than one currency before dominant-currency filtering.

attributed_revenue_centsinteger

Net attributed revenue in cents from the orders ledger.

deliveredinteger
attributed_ordersinteger
revenue_per_recipientnumber<float> | null

Net attributed revenue in major currency units divided by delivered recipients.

conversion_ratenumber<float> | null

Attributed paid orders divided by delivered recipients.

attributed_aovnumber<float> | null

Net attributed revenue in major currency units divided by attributed paid orders.

message_breakdownArray<RevenueMessageBreakdown>
Show child attributes
message_idinteger
subjectstring | null
sent_atstring<date-time> | null
currencystring | null

Dominant attributed order currency for this message row.

mixed_currencyboolean

True when attributed orders included more than one currency before dominant-currency filtering.

deliveredinteger
attributed_ordersinteger
attributed_revenue_centsinteger

Net attributed revenue in cents from the orders ledger.

revenue_per_recipientnumber<float> | null
conversion_ratenumber<float> | null
attributed_aovnumber<float> | null
draft_revision_idinteger | null
draft_revision_digeststring | null
draft_approval_statestring | nullpending_reviewapprovedrejected
active_revision_idinteger | null
active_revision_digeststring | null
has_unpublished_changesboolean
created_atstring<date-time>
updated_atstring<date-time>
templatesArray<Template>
Show child attributes
idinteger
namestring | null
flow_idinteger | null
action_idinteger | null
versioninteger
subjectstring | null
bodystring | null
preheaderstring | null
from_namestring | null
from_emailstring | null
reply_tostring | null
designEmailDesign | null
variablesobject
generation_provenanceGenerationProvenance

Candidate-bound generation evidence. Save endpoints accept only state: candidate values returned by the generation endpoint. Resource responses may return state: accepted as read-only history.

Show child attributes
statestringcandidateacceptedrequired
event_idintegerrequired
candidate_locatorstring
generated_slice_digeststring
acceptance_idinteger
saved_authored_digeststring
edit_relationstringidenticaledited
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "account_id": 0,
  "brand_id": 0,
  "status": "draft",
  "approval_state": "string",
  "name": "string",
  "goal": "string",
  "trigger": {
    "event": "string",
    "segment_id": 0,
    "contact_list_id": 0,
    "exclude_segment_ids": [
      0
    ],
    "data": {}
  },
  "steps": [],
  "sent_count": 0,
  "engagement": {
    "sent": 0,
    "opens": 0,
    "total_opens": 0,
    "open_rate": 0,
    "account": {
      "sent": 0,
      "opens": 0,
      "total_opens": 0,
      "open_rate": 0
    }
  },
  "revenue": {
    "attribution_label": "Attributed revenue. Last click, 7-day window.",
    "currency": "string",
    "mixed_currency": true,
    "attributed_revenue_cents": 0,
    "delivered": 0,
    "attributed_orders": 0,
    "revenue_per_recipient": 0,
    "conversion_rate": 0,
    "attributed_aov": 0,
    "message_breakdown": [
      {
        "message_id": 0,
        "subject": "string",
        "sent_at": "2024-01-15T09:30:00Z",
        "currency": "string",
        "mixed_currency": true,
        "delivered": 0,
        "attributed_orders": 0,
        "attributed_revenue_cents": 0,
        "revenue_per_recipient": 0,
        "conversion_rate": 0,
        "attributed_aov": 0
      }
    ]
  },
  "draft_revision_id": 0,
  "draft_revision_digest": "string",
  "draft_approval_state": "pending_review",
  "active_revision_id": 0,
  "active_revision_digest": "string",
  "has_unpublished_changes": true,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "templates": [
    {
      "id": 0,
      "name": "string",
      "flow_id": 0,
      "action_id": 0,
      "version": 0,
      "subject": "string",
      "body": "string",
      "preheader": "string",
      "from_name": "string",
      "from_email": "string",
      "reply_to": "string",
      "design": {
        "version": 1,
        "sections": [
          {
            "type": "header",
            "props": {},
            "styles": {
              "background_color": "string",
              "section_background_color": "string",
              "padding": "string",
              "align": "left",
              "scale": "display",
              "font_size": 0,
              "text_color": "string",
              "shape": "square",
              "remove_gap": true,
              "border_radius": 0
            }
          }
        ],
        "theme": {
          "brand_color": "string",
          "bg_color": "string",
          "text_color": "string",
          "font_body": "string",
          "font_heading": "string",
          "heading_size": 0,
          "body_size": 0,
          "radius": 0,
          "spacing_density": "compact",
          "button_background_color": "string",
          "button_text_color": "string",
          "button_padding": "string",
          "logo_url": "string",
          "company_name": "string",
          "physical_address": "string",
          "social_links": [
            {
              "platform": "string",
              "url": "string"
            }
          ]
        }
      },
      "variables": {},
      "generation_provenance": {
        "state": "candidate",
        "event_id": 0,
        "candidate_locator": "string",
        "generated_slice_digest": "string",
        "acceptance_id": 0,
        "saved_authored_digest": "string",
        "edit_relation": "identical"
      },
      "created_at": "2024-01-15T09:30:00Z",
      "updated_at": "2024-01-15T09:30:00Z"
    }
  ]
}

FlowResumePlan

object
flow_idintegerrequired
statusstringdraftlivepausedarchivedcancelledrequired
open_journey_countinteger>= 0required
contact_countinteger>= 0required
waiting_journey_countinteger>= 0required
scheduled_journey_countinteger>= 0required
has_unpublished_changesbooleanrequired
draft_approval_statestring | nullpending_reviewapprovedrejected
requires_choicebooleanrequired
allowed_modesArray<string>new_contacts_onlycontinue_existingrequired
recommended_modestringnew_contacts_onlyrequired
continue_release_interval_secondsinteger>= 1required
Example
{
  "flow_id": 0,
  "status": "draft",
  "open_journey_count": 0,
  "contact_count": 0,
  "waiting_journey_count": 0,
  "scheduled_journey_count": 0,
  "has_unpublished_changes": true,
  "draft_approval_state": "pending_review",
  "requires_choice": true,
  "allowed_modes": [
    "new_contacts_only"
  ],
  "recommended_mode": "new_contacts_only",
  "continue_release_interval_seconds": 1
}

FlowTemplate

object

Lean flow template card for index listings.

idstring

Template slug (e.g. welcome_series)

type_labelstring
descriptionstring
categorystring
email_countinteger
step_countinteger
preview_sectionsArray<object>

Section objects from the first email step's design, for template previews.

Example
{
  "id": "string",
  "type_label": "string",
  "description": "string",
  "category": "string",
  "email_count": 0,
  "step_count": 0,
  "preview_sections": [
    {}
  ]
}

FlowTemplateDetail

object

Lean flow template card for index listings.

idstring

Template slug (e.g. welcome_series)

type_labelstring
descriptionstring
categorystring
email_countinteger
step_countinteger
preview_sectionsArray<object>

Section objects from the first email step's design, for template previews.

Full flow template including the graph, ready for POST /v1/my/flows.

triggerobject

Trigger definition (pass as-is to POST /v1/my/flows trigger param)

stepsArray<object>

Step definitions (pass as-is to POST /v1/my/flows steps param)

Example
{
  "id": "string",
  "type_label": "string",
  "description": "string",
  "category": "string",
  "email_count": 0,
  "step_count": 0,
  "preview_sections": [
    {}
  ],
  "trigger": {},
  "steps": [
    {}
  ]
}

EngagementBucket

object

A (sent, opens, total_opens, open_rate) block. Used both for the resource itself and, nested as account, for the brand-level lifetime baseline.

sentintegerrequired

Total emails sent in this bucket.

opensintegerrequired

Unique human open events recorded in this bucket.

total_opensintegerrequired

All human open events including repeat opens by the same recipient, so total_opens >= opens. Falls back to opens when only unique-open data exists.

open_ratenumber<float> | nullrequired

Opens divided by sent, rounded to 4 decimal places. Null when sent is below the meaningful threshold for this bucket — zero for resource buckets, or below Report::Engagement::ACCOUNT_BASELINE_MIN_SENT for the account bucket.

Example
{
  "sent": 0,
  "opens": 0,
  "total_opens": 0,
  "open_rate": 0
}

Engagement

object

A (sent, opens, total_opens, open_rate) block. Used both for the resource itself and, nested as account, for the brand-level lifetime baseline.

sentintegerrequired

Total emails sent in this bucket.

opensintegerrequired

Unique human open events recorded in this bucket.

total_opensintegerrequired

All human open events including repeat opens by the same recipient, so total_opens >= opens. Falls back to opens when only unique-open data exists.

open_ratenumber<float> | nullrequired

Opens divided by sent, rounded to 4 decimal places. Null when sent is below the meaningful threshold for this bucket — zero for resource buckets, or below Report::Engagement::ACCOUNT_BASELINE_MIN_SENT for the account bucket.

accountEngagementBucketrequired

A (sent, opens, total_opens, open_rate) block. Used both for the resource itself and, nested as account, for the brand-level lifetime baseline.

Show child attributes
sentintegerrequired

Total emails sent in this bucket.

opensintegerrequired

Unique human open events recorded in this bucket.

total_opensintegerrequired

All human open events including repeat opens by the same recipient, so total_opens >= opens. Falls back to opens when only unique-open data exists.

open_ratenumber<float> | nullrequired

Opens divided by sent, rounded to 4 decimal places. Null when sent is below the meaningful threshold for this bucket — zero for resource buckets, or below Report::Engagement::ACCOUNT_BASELINE_MIN_SENT for the account bucket.

Example
{
  "sent": 0,
  "opens": 0,
  "total_opens": 0,
  "open_rate": 0,
  "account": {
    "sent": 0,
    "opens": 0,
    "total_opens": 0,
    "open_rate": 0
  }
}

RevenueMessageBreakdown

object
message_idinteger
subjectstring | null
sent_atstring<date-time> | null
currencystring | null

Dominant attributed order currency for this message row.

mixed_currencyboolean

True when attributed orders included more than one currency before dominant-currency filtering.

deliveredinteger
attributed_ordersinteger
attributed_revenue_centsinteger

Net attributed revenue in cents from the orders ledger.

revenue_per_recipientnumber<float> | null
conversion_ratenumber<float> | null
attributed_aovnumber<float> | null
Example
{
  "message_id": 0,
  "subject": "string",
  "sent_at": "2024-01-15T09:30:00Z",
  "currency": "string",
  "mixed_currency": true,
  "delivered": 0,
  "attributed_orders": 0,
  "attributed_revenue_cents": 0,
  "revenue_per_recipient": 0,
  "conversion_rate": 0,
  "attributed_aov": 0
}

RevenueReport

object

Attributed revenue from the orders ledger. This block is omitted when the brand has no connected Shopify or Stripe revenue source.

attribution_labelstring
currencystring | null

Dominant attributed order currency used for revenue math. Null when no attributed orders carry a currency.

mixed_currencyboolean

True when attributed orders included more than one currency before dominant-currency filtering.

attributed_revenue_centsinteger

Net attributed revenue in cents from the orders ledger.

deliveredinteger
attributed_ordersinteger
revenue_per_recipientnumber<float> | null

Net attributed revenue in major currency units divided by delivered recipients.

conversion_ratenumber<float> | null

Attributed paid orders divided by delivered recipients.

attributed_aovnumber<float> | null

Net attributed revenue in major currency units divided by attributed paid orders.

message_breakdownArray<RevenueMessageBreakdown>
Show child attributes
message_idinteger
subjectstring | null
sent_atstring<date-time> | null
currencystring | null

Dominant attributed order currency for this message row.

mixed_currencyboolean

True when attributed orders included more than one currency before dominant-currency filtering.

deliveredinteger
attributed_ordersinteger
attributed_revenue_centsinteger

Net attributed revenue in cents from the orders ledger.

revenue_per_recipientnumber<float> | null
conversion_ratenumber<float> | null
attributed_aovnumber<float> | null
Example
{
  "attribution_label": "Attributed revenue. Last click, 7-day window.",
  "currency": "string",
  "mixed_currency": true,
  "attributed_revenue_cents": 0,
  "delivered": 0,
  "attributed_orders": 0,
  "revenue_per_recipient": 0,
  "conversion_rate": 0,
  "attributed_aov": 0,
  "message_breakdown": [
    {
      "message_id": 0,
      "subject": "string",
      "sent_at": "2024-01-15T09:30:00Z",
      "currency": "string",
      "mixed_currency": true,
      "delivered": 0,
      "attributed_orders": 0,
      "attributed_revenue_cents": 0,
      "revenue_per_recipient": 0,
      "conversion_rate": 0,
      "attributed_aov": 0
    }
  ]
}

FlowTrigger

object
idinteger
flow_idinteger
eventstring
audience_typestring | nulllistssegmentall_contacts

Explicit campaign audience target; null means no audience selected.

segment_idinteger | null
contact_list_idinteger | nulldeprecated

Deprecated — use contact_list_ids

contact_list_idsArray<integer>

Contact list IDs targeted by this trigger

exclude_segment_idsArray<integer>

Segment IDs whose matching contacts are excluded from the recipient set

exclude_contact_list_idsArray<integer>

Contact list IDs whose members are excluded from the recipient set

dataobject | null
triggered_countinteger
last_triggered_atstring<date-time> | null
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "flow_id": 0,
  "event": "string",
  "audience_type": "lists",
  "segment_id": 0,
  "contact_list_id": 0,
  "contact_list_ids": [
    0
  ],
  "exclude_segment_ids": [
    0
  ],
  "exclude_contact_list_ids": [
    0
  ],
  "data": {},
  "triggered_count": 0,
  "last_triggered_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

FlowTriggerInput

object
eventstring

Built-in: contact_add, keyword, message, list_add, list_remove, product_view, checkout, cart_add, cart_remove, cart_abandoned, browse_abandoned. Custom: any lowercase alphanumeric with underscores.

audience_typestring | nulllistssegmentall_contacts

Explicit campaign audience target; null means no audience selected.

segment_idinteger | null
contact_list_idinteger | nulldeprecated

Deprecated — use contact_list_ids

contact_list_idsArray<integer>

Contact list IDs to target

exclude_segment_idsArray<integer>

Segment IDs whose matching contacts are excluded from the recipient set; pass [] to clear

dataobject
Example
{
  "event": "string",
  "audience_type": "lists",
  "segment_id": 0,
  "contact_list_id": 0,
  "contact_list_ids": [
    0
  ],
  "exclude_segment_ids": [
    0
  ],
  "data": {}
}

FlowTriggerOutput

object

Trigger as returned by Flow::Format.dump

eventstring
segment_idinteger | null
contact_list_idinteger | null
exclude_segment_idsArray<integer>

Segment IDs whose matching contacts are excluded from the recipient set

dataobject | null
Example
{
  "event": "string",
  "segment_id": 0,
  "contact_list_id": 0,
  "exclude_segment_ids": [
    0
  ],
  "data": {}
}

FlowStepInput

object
typestringemailsmswaitsplitemit_eventrequired
subjectstring

Email step: subject line

bodystring

SMS body or email plain text

preheaderstring

Email step: preheader

from_namestring
from_emailstring
reply_tostring
designEmailDesign

Email template design document

Show child attributes
versioninteger>= 1
sectionsArray<EmailSection>
Show child attributes
typestringheaderherotextimagebuttoncolumnsproductproductsgallerysocialdividerspacerfooterrequired
propsobject

Section-specific properties (see email component spec)

stylesobject
Show child attributes
background_colorstring
section_background_colorstring
paddingstring
alignstringleftcenterright
scalestringdisplayposter
font_sizeinteger
text_colorstring
shapestringsquareroundedarchcircle
remove_gapboolean
border_radiusinteger
themeobject

Theme overrides merged on top of brand theme

Show child attributes
brand_colorstring
bg_colorstring
text_colorstring
font_bodystring
font_headingstring
heading_sizeinteger
body_sizeinteger
radiusinteger
spacing_densitystringcompactnormalspacious
button_background_colorstring
button_text_colorstring
button_paddingstring
logo_urlstring
company_namestring
physical_addressstring
social_linksArray<object>
Show child attributes
platformstring
urlstring
durationinteger

Wait step: seconds

filtersSegmentFilterExpression
yesArray<FlowStepInput>

Split step: yes branch

noArray<FlowStepInput>

Split step: no branch

event_namestring

Emit event step: event to fire

forward_event_databooleanfalse
event_dataobject
transactionalbooleanfalse
Example
{
  "type": "email",
  "subject": "string",
  "body": "string",
  "preheader": "string",
  "from_name": "string",
  "from_email": "string",
  "reply_to": "string",
  "design": {
    "version": 1,
    "sections": [
      {
        "type": "header",
        "props": {},
        "styles": {
          "background_color": "string",
          "section_background_color": "string",
          "padding": "string",
          "align": "left",
          "scale": "display",
          "font_size": 0,
          "text_color": "string",
          "shape": "square",
          "remove_gap": true,
          "border_radius": 0
        }
      }
    ],
    "theme": {
      "brand_color": "string",
      "bg_color": "string",
      "text_color": "string",
      "font_body": "string",
      "font_heading": "string",
      "heading_size": 0,
      "body_size": 0,
      "radius": 0,
      "spacing_density": "compact",
      "button_background_color": "string",
      "button_text_color": "string",
      "button_padding": "string",
      "logo_url": "string",
      "company_name": "string",
      "physical_address": "string",
      "social_links": [
        {
          "platform": "string",
          "url": "string"
        }
      ]
    }
  },
  "duration": 0,
  "yes": [],
  "no": [],
  "event_name": "string",
  "forward_event_data": false,
  "event_data": {},
  "transactional": false
}

FlowStepOutput

object

Step as returned by Flow::Format.dump

typestringemailsmswaitsplitemit_event
subjectstring
bodystring
preheaderstring
durationinteger
filtersArray<object>
yesArray<FlowStepOutput>
noArray<FlowStepOutput>
event_namestring
forward_event_databoolean
Example
{
  "type": "email",
  "subject": "string",
  "body": "string",
  "preheader": "string",
  "duration": 0,
  "filters": [
    {}
  ],
  "yes": [],
  "no": [],
  "event_name": "string",
  "forward_event_data": true
}

Event

object
idinteger
account_idinteger
contact_idinteger
user_idinteger
eventstring
amountnumber<double> | null
dataobject
idempotency_keystring | null
resource_uidstring | null
resource_namestring | null
resource_urlstring | null
testboolean
generatedboolean
chain_depthinteger
ipstring | null
user_agentstring | null
browserstring | null
osstring | null
device_typestring | null
referrerstring | null
utm_sourcestring | null
utm_mediumstring | null
utm_termstring | null
utm_contentstring | null
utm_campaignstring | null
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "account_id": 0,
  "contact_id": 0,
  "user_id": 0,
  "event": "string",
  "amount": 0,
  "data": {},
  "idempotency_key": "string",
  "resource_uid": "string",
  "resource_name": "string",
  "resource_url": "string",
  "test": true,
  "generated": true,
  "chain_depth": 0,
  "ip": "string",
  "user_agent": "string",
  "browser": "string",
  "os": "string",
  "device_type": "string",
  "referrer": "string",
  "utm_source": "string",
  "utm_medium": "string",
  "utm_term": "string",
  "utm_content": "string",
  "utm_campaign": "string",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

Domain

object
idinteger
brand_idinteger | null
namestring
providerstringses
default_from_domainstring

Domain Nitrosend will use for visible From addresses when this sending domain is selected.

sender_authorization_reasonstringmissing_sender_domainexact_inboxshared_domain_requires_exact_inboxshared_domain_not_verifiedplatform_domainsender_domain_not_authorizedsending_domainunaligned_apex_supportedauthor_identity_not_verifiedauthor_domain_unalignedauthor_domainsender_domain_mismatch

Machine-readable reason the default visible From domain is or is not authorized.

integration_idinteger | null
statusstringpendingverified
dmarc_policystringnonequarantinereject

Effective observed DMARC policy persisted by Nitrosend; defaults to none until observed.

dmarc_recommended_policystringnonequarantinereject

Nitrosend's recommended DMARC policy rung.

dmarc_observed_policystring | nullnonequarantinereject

Last live DMARC policy observed by Nitrosend.

dns_recordsDomainDnsRecords | null
Show child attributes
sending_dns_recordsArray<DomainDnsRecord>
Show child attributes
record_typestring
namestring
relative_namestring

Record name relative to the registrable domain, as most registrars' Host field expects; @ for the apex.

valuestring
prioritystring | null
validstring | null
purposestring | null
requiredboolean | null
mail_forwardingDomainMailForwarding | null
receiving_dns_recordsArray<DomainDnsRecord>
Show child attributes
record_typestring
namestring
relative_namestring

Record name relative to the registrable domain, as most registrars' Host field expects; @ for the apex.

valuestring
prioritystring | null
validstring | null
purposestring | null
requiredboolean | null
mail_forwardingDomainMailForwarding | null
inbound_setupDomainInboundSetup | null
dns_healthobject | null
dns_setup_statusstringuncheckedincompletereadyverified
verified_atstring<date-time> | null
created_atstring<date-time>
Example
{
  "id": 0,
  "brand_id": 0,
  "name": "string",
  "provider": "ses",
  "default_from_domain": "string",
  "sender_authorization_reason": "missing_sender_domain",
  "integration_id": 0,
  "status": "pending",
  "dmarc_policy": "none",
  "dmarc_recommended_policy": "none",
  "dmarc_observed_policy": "none",
  "dns_records": {
    "sending_dns_records": [
      {
        "record_type": "string",
        "name": "string",
        "relative_name": "string",
        "value": "string",
        "priority": "string",
        "valid": "string",
        "purpose": "string",
        "required": true,
        "mail_forwarding": {
          "enabled": true,
          "route_type": "legacy_forward_all",
          "destination_type": "legacy_mx",
          "legacy_mx_records": [
            {
              "host": "string",
              "preference": 0
            }
          ],
          "setup_note": "string"
        }
      }
    ],
    "receiving_dns_records": [
      {
        "record_type": "string",
        "name": "string",
        "relative_name": "string",
        "value": "string",
        "priority": "string",
        "valid": "string",
        "purpose": "string",
        "required": true,
        "mail_forwarding": {
          "enabled": true,
          "route_type": "legacy_forward_all",
          "destination_type": "legacy_mx",
          "legacy_mx_records": [
            {
              "host": "string",
              "preference": 0
            }
          ],
          "setup_note": "string"
        }
      }
    ]
  },
  "inbound_setup": {
    "method": "none",
    "status": "not_configured",
    "mx_scope": "apex",
    "inbox": {
      "id": 0,
      "address": "user@example.com",
      "display_name": "string",
      "status": "active"
    },
    "provider_forwarding": {
      "provider": "google_workspace",
      "forwarding_address": "user@example.com",
      "probe_sent_at": "2024-01-15T09:30:00Z",
      "verified_at": "2024-01-15T09:30:00Z"
    },
    "apex_mx": {
      "mode": "standalone",
      "preparation": {
        "state": "queued",
        "message": "string",
        "failure_code": "string"
      },
      "prepared": true,
      "configured": true,
      "approval_required": true,
      "approval_expires_at": "2024-01-15T09:30:00Z",
      "legacy_provider_label": "string",
      "legacy_mx_records": [
        {
          "host": "string",
          "preference": 0
        }
      ],
      "setup_note": "string"
    }
  },
  "dns_health": {},
  "dns_setup_status": "unchecked",
  "verified_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z"
}

EntriSessionResponse

object
domainDomainrequired
Show child attributes
idinteger
brand_idinteger | null
namestring
providerstringses
default_from_domainstring

Domain Nitrosend will use for visible From addresses when this sending domain is selected.

sender_authorization_reasonstringmissing_sender_domainexact_inboxshared_domain_requires_exact_inboxshared_domain_not_verifiedplatform_domainsender_domain_not_authorizedsending_domainunaligned_apex_supportedauthor_identity_not_verifiedauthor_domain_unalignedauthor_domainsender_domain_mismatch

Machine-readable reason the default visible From domain is or is not authorized.

integration_idinteger | null
statusstringpendingverified
dmarc_policystringnonequarantinereject

Effective observed DMARC policy persisted by Nitrosend; defaults to none until observed.

dmarc_recommended_policystringnonequarantinereject

Nitrosend's recommended DMARC policy rung.

dmarc_observed_policystring | nullnonequarantinereject

Last live DMARC policy observed by Nitrosend.

dns_recordsDomainDnsRecords | null
Show child attributes
sending_dns_recordsArray<DomainDnsRecord>
Show child attributes
record_typestring
namestring
relative_namestring

Record name relative to the registrable domain, as most registrars' Host field expects; @ for the apex.

valuestring
prioritystring | null
validstring | null
purposestring | null
requiredboolean | null
mail_forwardingDomainMailForwarding | null
receiving_dns_recordsArray<DomainDnsRecord>
Show child attributes
record_typestring
namestring
relative_namestring

Record name relative to the registrable domain, as most registrars' Host field expects; @ for the apex.

valuestring
prioritystring | null
validstring | null
purposestring | null
requiredboolean | null
mail_forwardingDomainMailForwarding | null
inbound_setupDomainInboundSetup | null
dns_healthobject | null
dns_setup_statusstringuncheckedincompletereadyverified
verified_atstring<date-time> | null
created_atstring<date-time>
entriobjectrequired
Show child attributes
application_idstringrequired
tokenstringrequired
prefilled_domainstringrequired
user_idstringrequired
dns_recordsArray<EntriDnsRecord>required
Show child attributes
typestring
hoststring
valuestring
ttlinteger
priorityinteger | null
manual_dns_recordsDomainDnsRecordsrequired
Show child attributes
sending_dns_recordsArray<DomainDnsRecord>
Show child attributes
record_typestring
namestring
relative_namestring

Record name relative to the registrable domain, as most registrars' Host field expects; @ for the apex.

valuestring
prioritystring | null
validstring | null
purposestring | null
requiredboolean | null
mail_forwardingDomainMailForwarding | null
receiving_dns_recordsArray<DomainDnsRecord>
Show child attributes
record_typestring
namestring
relative_namestring

Record name relative to the registrable domain, as most registrars' Host field expects; @ for the apex.

valuestring
prioritystring | null
validstring | null
purposestring | null
requiredboolean | null
mail_forwardingDomainMailForwarding | null
Example
{
  "domain": {
    "id": 0,
    "brand_id": 0,
    "name": "string",
    "provider": "ses",
    "default_from_domain": "string",
    "sender_authorization_reason": "missing_sender_domain",
    "integration_id": 0,
    "status": "pending",
    "dmarc_policy": "none",
    "dmarc_recommended_policy": "none",
    "dmarc_observed_policy": "none",
    "dns_records": {
      "sending_dns_records": [
        {
          "record_type": "string",
          "name": "string",
          "relative_name": "string",
          "value": "string",
          "priority": "string",
          "valid": "string",
          "purpose": "string",
          "required": true,
          "mail_forwarding": {
            "enabled": true,
            "route_type": "legacy_forward_all",
            "destination_type": "legacy_mx",
            "legacy_mx_records": [
              {
                "host": "string",
                "preference": 0
              }
            ],
            "setup_note": "string"
          }
        }
      ],
      "receiving_dns_records": [
        {
          "record_type": "string",
          "name": "string",
          "relative_name": "string",
          "value": "string",
          "priority": "string",
          "valid": "string",
          "purpose": "string",
          "required": true,
          "mail_forwarding": {
            "enabled": true,
            "route_type": "legacy_forward_all",
            "destination_type": "legacy_mx",
            "legacy_mx_records": [
              {
                "host": "string",
                "preference": 0
              }
            ],
            "setup_note": "string"
          }
        }
      ]
    },
    "inbound_setup": {
      "method": "none",
      "status": "not_configured",
      "mx_scope": "apex",
      "inbox": {
        "id": 0,
        "address": "user@example.com",
        "display_name": "string",
        "status": "active"
      },
      "provider_forwarding": {
        "provider": "google_workspace",
        "forwarding_address": "user@example.com",
        "probe_sent_at": "2024-01-15T09:30:00Z",
        "verified_at": "2024-01-15T09:30:00Z"
      },
      "apex_mx": {
        "mode": "standalone",
        "preparation": {
          "state": "queued",
          "message": "string",
          "failure_code": "string"
        },
        "prepared": true,
        "configured": true,
        "approval_required": true,
        "approval_expires_at": "2024-01-15T09:30:00Z",
        "legacy_provider_label": "string",
        "legacy_mx_records": [
          {
            "host": "string",
            "preference": 0
          }
        ],
        "setup_note": "string"
      }
    },
    "dns_health": {},
    "dns_setup_status": "unchecked",
    "verified_at": "2024-01-15T09:30:00Z",
    "created_at": "2024-01-15T09:30:00Z"
  },
  "entri": {
    "application_id": "string",
    "token": "string",
    "prefilled_domain": "string",
    "user_id": "string",
    "dns_records": [
      {
        "type": "string",
        "host": "string",
        "value": "string",
        "ttl": 0,
        "priority": 0
      }
    ],
    "manual_dns_records": {
      "sending_dns_records": [
        {
          "record_type": "string",
          "name": "string",
          "relative_name": "string",
          "value": "string",
          "priority": "string",
          "valid": "string",
          "purpose": "string",
          "required": true,
          "mail_forwarding": {
            "enabled": true,
            "route_type": "legacy_forward_all",
            "destination_type": "legacy_mx",
            "legacy_mx_records": [
              {
                "host": "string",
                "preference": 0
              }
            ],
            "setup_note": "string"
          }
        }
      ],
      "receiving_dns_records": [
        {
          "record_type": "string",
          "name": "string",
          "relative_name": "string",
          "value": "string",
          "priority": "string",
          "valid": "string",
          "purpose": "string",
          "required": true,
          "mail_forwarding": {
            "enabled": true,
            "route_type": "legacy_forward_all",
            "destination_type": "legacy_mx",
            "legacy_mx_records": [
              {
                "host": "string",
                "preference": 0
              }
            ],
            "setup_note": "string"
          }
        }
      ]
    }
  }
}

EntriSessionRequest

object
apex_mx_overridebooleanfalse

Explicitly include the prepared company-inbox MX cutover in this session.

apex_mx_confirmationstring

Exact apex domain name being approved. Required when apex_mx_override is true.

Example
{
  "apex_mx_override": false,
  "apex_mx_confirmation": "string"
}

EntriSessionValidationError

object
capacity_recoveryDeliveryCapacityRecovery

Informational recovery at 80 percent used, exhaustion, or when a campaign exceeds remaining allowance. Never denies a send or promises that payment or verification bypasses safety. Actions come from the shared backend projection; only offer verification when new valid proof can improve standing.

Show child attributes
statestringapproachingreachedcampaign_exceeds_remainingrequired
reason_codestringsending_capacity_warningsending_capacity_reachedrequired
blocking_controlstringcommercial_capacityrequired
usage_percentinteger[0, 100]required
requested_quantityinteger>= 0
labelstringrequired
detailstringrequired
capacityDeliveryCapacityrequired
Show child attributes
sourcestringplanoperator_override
window_secondsinteger
statusstringknownunlimitednot_applicableunknowndegradedrequired
limitinteger | null>= 0required
reservedinteger | null>= 0required
acceptedinteger | null>= 0required
provider_unknowninteger | null>= 0required
remaininginteger | null>= 0required
upgrade_urlstring<uri>

Shareable account-specific plan link. Authentication and billing permissions still apply.

retry_atstring<date-time>

Recorded retry time, not a guarantee that delivery completes then.

recovery_actionDeliveryCapacityRecoveryActionrequired
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
recovery_actionsArray<DeliveryCapacityRecoveryAction>required
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
owner_actionDeliveryCapacityRecoveryActionrequired
Show child attributes
typestringupgrade_planverify_listcontact_ownermanage_provider_billingcontact_supportrequired
labelstringrequired
detailstring
urlstring<uri>required
required_rolestring
recovery_actionobject

Context-specific recovery action, including sending capacity or prepaid funding recovery.

codeintegerrequired
messagestringrequired
errorbooleanrequired
error_codestring | null

Optional machine-readable error reason.

provisioning_idinteger | null

Existing provisioning row involved in a managed-account conflict.

retryableboolean

Whether retrying the same idempotent operation can succeed.

retry_atstring<date-time>

Earliest recommended retry time for a retryable failure.

blockersArray<string>

Machine-readable reasons the apex MX cutover cannot proceed.

Example
{
  "capacity_recovery": {
    "state": "approaching",
    "reason_code": "sending_capacity_warning",
    "blocking_control": "commercial_capacity",
    "usage_percent": 0,
    "requested_quantity": 0,
    "label": "string",
    "detail": "string",
    "capacity": {
      "source": "plan",
      "window_seconds": 86400,
      "status": "known",
      "limit": 0,
      "reserved": 0,
      "accepted": 0,
      "provider_unknown": 0,
      "remaining": 0
    },
    "upgrade_url": "https://example.com",
    "retry_at": "2024-01-15T09:30:00Z",
    "recovery_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    },
    "recovery_actions": [
      {
        "type": "upgrade_plan",
        "label": "string",
        "detail": "string",
        "url": "https://example.com",
        "required_role": "account_owner_or_admin"
      }
    ],
    "owner_action": {
      "type": "upgrade_plan",
      "label": "string",
      "detail": "string",
      "url": "https://example.com",
      "required_role": "account_owner_or_admin"
    }
  },
  "recovery_action": {},
  "code": 0,
  "message": "string",
  "error": true,
  "error_code": "string",
  "provisioning_id": 0,
  "retryable": true,
  "retry_at": "2024-01-15T09:30:00Z",
  "blockers": [
    "string"
  ]
}

DomainDnsRecords

object
sending_dns_recordsArray<DomainDnsRecord>
Show child attributes
record_typestring
namestring
relative_namestring

Record name relative to the registrable domain, as most registrars' Host field expects; @ for the apex.

valuestring
prioritystring | null
validstring | null
purposestring | null
requiredboolean | null
mail_forwardingDomainMailForwarding | null
receiving_dns_recordsArray<DomainDnsRecord>
Show child attributes
record_typestring
namestring
relative_namestring

Record name relative to the registrable domain, as most registrars' Host field expects; @ for the apex.

valuestring
prioritystring | null
validstring | null
purposestring | null
requiredboolean | null
mail_forwardingDomainMailForwarding | null
Example
{
  "sending_dns_records": [
    {
      "record_type": "string",
      "name": "string",
      "relative_name": "string",
      "value": "string",
      "priority": "string",
      "valid": "string",
      "purpose": "string",
      "required": true,
      "mail_forwarding": {
        "enabled": true,
        "route_type": "legacy_forward_all",
        "destination_type": "legacy_mx",
        "legacy_mx_records": [
          {
            "host": "string",
            "preference": 0
          }
        ],
        "setup_note": "string"
      }
    }
  ],
  "receiving_dns_records": [
    {
      "record_type": "string",
      "name": "string",
      "relative_name": "string",
      "value": "string",
      "priority": "string",
      "valid": "string",
      "purpose": "string",
      "required": true,
      "mail_forwarding": {
        "enabled": true,
        "route_type": "legacy_forward_all",
        "destination_type": "legacy_mx",
        "legacy_mx_records": [
          {
            "host": "string",
            "preference": 0
          }
        ],
        "setup_note": "string"
      }
    }
  ]
}

DomainDnsRecord

object
record_typestring
namestring
relative_namestring

Record name relative to the registrable domain, as most registrars' Host field expects; @ for the apex.

valuestring
prioritystring | null
validstring | null
purposestring | null
requiredboolean | null
mail_forwardingDomainMailForwarding | null
Example
{
  "record_type": "string",
  "name": "string",
  "relative_name": "string",
  "value": "string",
  "priority": "string",
  "valid": "string",
  "purpose": "string",
  "required": true,
  "mail_forwarding": {
    "enabled": true,
    "route_type": "legacy_forward_all",
    "destination_type": "legacy_mx",
    "legacy_mx_records": [
      {
        "host": "string",
        "preference": 0
      }
    ],
    "setup_note": "string"
  }
}

DomainMailForwarding

object
enabledbooleanrequired
route_typestringlegacy_forward_allunmatched_forwardrequired
destination_typestringlegacy_mxsmtp_relayrequired
legacy_mx_recordsArray<MxRecord>required
Show child attributes
hoststringrequired
preferenceintegerrequired
setup_notestringrequired
Example
{
  "enabled": true,
  "route_type": "legacy_forward_all",
  "destination_type": "legacy_mx",
  "legacy_mx_records": [
    {
      "host": "string",
      "preference": 0
    }
  ],
  "setup_note": "string"
}

DomainInboundSetupRequest

object
inbound_setupobjectrequired
Show child attributes
methodstringprovider_forwardingmxrequired
providerstringgoogle_workspacemicrosoft_365

Required when method is provider_forwarding.

local_partstring

Required when the domain does not yet have its included inbox.

display_namestring | null
preparebooleanfalse

Prepare apex receiving before opening the existing Entri MX connection. Does not change DNS.

no_existing_mail_servicebooleanfalse

Explicit first-mailbox choice. Rejected when public MX or a saved route identifies an existing mail service.

Example
{
  "inbound_setup": {
    "method": "provider_forwarding",
    "provider": "google_workspace",
    "local_part": "string",
    "display_name": "string",
    "prepare": false,
    "no_existing_mail_service": false
  }
}

DomainInboundSetup

object
methodstringnoneprovider_forwardingmxrequired
statusstringnot_configuredpendingactiveattentionrequired
mx_scopestring | nullapexsubdomain
inboxDomainInboundInbox | null
provider_forwardingDomainProviderForwarding | null
apex_mxDomainApexMxSetup | null
Example
{
  "method": "none",
  "status": "not_configured",
  "mx_scope": "apex",
  "inbox": {
    "id": 0,
    "address": "user@example.com",
    "display_name": "string",
    "status": "active"
  },
  "provider_forwarding": {
    "provider": "google_workspace",
    "forwarding_address": "user@example.com",
    "probe_sent_at": "2024-01-15T09:30:00Z",
    "verified_at": "2024-01-15T09:30:00Z"
  },
  "apex_mx": {
    "mode": "standalone",
    "preparation": {
      "state": "queued",
      "message": "string",
      "failure_code": "string"
    },
    "prepared": true,
    "configured": true,
    "approval_required": true,
    "approval_expires_at": "2024-01-15T09:30:00Z",
    "legacy_provider_label": "string",
    "legacy_mx_records": [
      {
        "host": "string",
        "preference": 0
      }
    ],
    "setup_note": "string"
  }
}

DomainInboundInbox

object
idintegerrequired
addressstring<email>required
display_namestring | null
statusstringactivedisabledarchivedrequired
Example
{
  "id": 0,
  "address": "user@example.com",
  "display_name": "string",
  "status": "active"
}

DomainProviderForwarding

object
providerstringgoogle_workspacemicrosoft_365required
forwarding_addressstring<email>requiredread only
probe_sent_atstring<date-time> | null
verified_atstring<date-time> | null
Example
{
  "provider": "google_workspace",
  "forwarding_address": "user@example.com",
  "probe_sent_at": "2024-01-15T09:30:00Z",
  "verified_at": "2024-01-15T09:30:00Z"
}

DomainApexMxSetup

object
modestringstandaloneforward_all
preparationobject
Show child attributes
statestringqueuedpreparingprobingreadyfailed
messagestring
failure_codestring
preparedbooleanrequired
configuredbooleanrequired
approval_requiredbooleanrequired
approval_expires_atstring<date-time> | null
legacy_provider_labelstring | null
legacy_mx_recordsArray<MxRecord>required
Show child attributes
hoststringrequired
preferenceintegerrequired
setup_notestring | null
Example
{
  "mode": "standalone",
  "preparation": {
    "state": "queued",
    "message": "string",
    "failure_code": "string"
  },
  "prepared": true,
  "configured": true,
  "approval_required": true,
  "approval_expires_at": "2024-01-15T09:30:00Z",
  "legacy_provider_label": "string",
  "legacy_mx_records": [
    {
      "host": "string",
      "preference": 0
    }
  ],
  "setup_note": "string"
}

MxRecord

object
hoststringrequired
preferenceintegerrequired
Example
{
  "host": "string",
  "preference": 0
}

EntriDnsRecord

object
typestring
hoststring
valuestring
ttlinteger
priorityinteger | null
Example
{
  "type": "string",
  "host": "string",
  "value": "string",
  "ttl": 0,
  "priority": 0
}

Integration

object
idinteger
providerstringmailgunsespostmarkresendsendgridtwilioattiohubspotmailchimpstripeshopifyapollo
categorystringemailsmscrmrevenueecommercedata
activeboolean
primaryboolean
statusstringpendingconnectederror
connected_atstring<date-time> | null
last_tested_atstring<date-time> | null
error_messagestring | null
config_summaryobject
secret_hintsobject
created_atstring<date-time>
updated_atstring<date-time>
Example
{
  "id": 0,
  "provider": "mailgun",
  "category": "email",
  "active": true,
  "primary": true,
  "status": "pending",
  "connected_at": "2024-01-15T09:30:00Z",
  "last_tested_at": "2024-01-15T09:30:00Z",
  "error_message": "string",
  "config_summary": {},
  "secret_hints": {},
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z"
}

ShopifyMerchantCredentialRequest

object
shopifyobjectrequired
Show child attributes
shopstringrequired

Permanent myshopify.com domain or shop slug.

client_idstringrequiredwrite only

Client ID for the merchant-owned Shopify app.

client_secretstring<password>requiredwrite only

Client secret for the merchant-owned Shopify app.

Example
{
  "shopify": {
    "shop": "string",
    "client_id": "string",
    "client_secret": "********"
  }
}

IntegrationWriteRequest

object
integrationMailgunIntegrationInput | SesIntegrationInput | PostmarkIntegrationInput | ResendIntegrationInput | SendgridIntegrationInputrequired
Example
{
  "integration": {
    "provider": "mailgun",
    "api_key": "string",
    "domain": "string",
    "region": "string",
    "active": true
  }
}

IntegrationSyncConfiguration

object
integration_idintegerrequired
providerstringrequired
sync_contractIntegrationSyncContractrequired
Show child attributes
versioninteger1required
mirror_listsbooleanrequired
updated_atstring<date-time> | null
objectsArray<IntegrationSyncObjectSelection>required
Show child attributes
object_idstring
object_slugstringrequired
labelstring
modestringaddressablerelatedrequired
enabledbooleantrue
field_policystringall_supportedselected
selected_fieldsArray<string>
excluded_fieldsArray<string>
relationshipobject
Show child attributes
attribute_slugstring
target_object_slugstringpeopleusers
trait_mappingIntegrationSyncTraitMapping
Show child attributes
kindstringdeal_pipelinerequired
stage_attributestringrequired
closed_stage_valuesArray<string>required
amount_attributestring
currency_attributestring
managed_audience_mapping_keystring
mirror_listsboolean
Example
{
  "integration_id": 0,
  "provider": "string",
  "sync_contract": {
    "version": 1,
    "mirror_lists": true,
    "updated_at": "2024-01-15T09:30:00Z",
    "objects": [
      {
        "object_id": "string",
        "object_slug": "string",
        "label": "string",
        "mode": "addressable",
        "enabled": true,
        "field_policy": "all_supported",
        "selected_fields": [
          "string"
        ],
        "excluded_fields": [
          "string"
        ],
        "relationship": {
          "attribute_slug": "string",
          "target_object_slug": "people"
        },
        "trait_mapping": {
          "kind": "deal_pipeline",
          "stage_attribute": "string",
          "closed_stage_values": [
            "string"
          ],
          "amount_attribute": "string",
          "currency_attribute": "string"
        },
        "managed_audience_mapping_key": "string",
        "mirror_lists": true
      }
    ]
  }
}

IntegrationSyncContract

object
versioninteger1required
mirror_listsbooleanrequired
updated_atstring<date-time> | null
objectsArray<IntegrationSyncObjectSelection>required
Show child attributes
object_idstring
object_slugstringrequired
labelstring
modestringaddressablerelatedrequired
enabledbooleantrue
field_policystringall_supportedselected
selected_fieldsArray<string>
excluded_fieldsArray<string>
relationshipobject
Show child attributes
attribute_slugstring
target_object_slugstringpeopleusers
trait_mappingIntegrationSyncTraitMapping
Show child attributes
kindstringdeal_pipelinerequired
stage_attributestringrequired
closed_stage_valuesArray<string>required
amount_attributestring
currency_attributestring
managed_audience_mapping_keystring
mirror_listsboolean
Example
{
  "version": 1,
  "mirror_lists": true,
  "updated_at": "2024-01-15T09:30:00Z",
  "objects": [
    {
      "object_id": "string",
      "object_slug": "string",
      "label": "string",
      "mode": "addressable",
      "enabled": true,
      "field_policy": "all_supported",
      "selected_fields": [
        "string"
      ],
      "excluded_fields": [
        "string"
      ],
      "relationship": {
        "attribute_slug": "string",
        "target_object_slug": "people"
      },
      "trait_mapping": {
        "kind": "deal_pipeline",
        "stage_attribute": "string",
        "closed_stage_values": [
          "string"
        ],
        "amount_attribute": "string",
        "currency_attribute": "string"
      },
      "managed_audience_mapping_key": "string",
      "mirror_lists": true
    }
  ]
}

IntegrationSyncObjectSelection

object
object_idstring
object_slugstringrequired
labelstring
modestringaddressablerelatedrequired
enabledbooleantrue
field_policystringall_supportedselected
selected_fieldsArray<string>
excluded_fieldsArray<string>
relationshipobject
Show child attributes
attribute_slugstring
target_object_slugstringpeopleusers
trait_mappingIntegrationSyncTraitMapping
Show child attributes
kindstringdeal_pipelinerequired
stage_attributestringrequired
closed_stage_valuesArray<string>required
amount_attributestring
currency_attributestring
managed_audience_mapping_keystring
mirror_listsboolean
Example
{
  "object_id": "string",
  "object_slug": "string",
  "label": "string",
  "mode": "addressable",
  "enabled": true,
  "field_policy": "all_supported",
  "selected_fields": [
    "string"
  ],
  "excluded_fields": [
    "string"
  ],
  "relationship": {
    "attribute_slug": "string",
    "target_object_slug": "people"
  },
  "trait_mapping": {
    "kind": "deal_pipeline",
    "stage_attribute": "string",
    "closed_stage_values": [
      "string"
    ],
    "amount_attribute": "string",
    "currency_attribute": "string"
  },
  "managed_audience_mapping_key": "string",
  "mirror_lists": true
}

IntegrationSyncTraitMapping

object
kindstringdeal_pipelinerequired
stage_attributestringrequired
closed_stage_valuesArray<string>required
amount_attributestring
currency_attributestring
Example
{
  "kind": "deal_pipeline",
  "stage_attribute": "string",
  "closed_stage_values": [
    "string"
  ],
  "amount_attribute": "string",
  "currency_attribute": "string"
}

IntegrationSyncConfigurationWriteRequest

object
sync_contractIntegrationSyncContractrequired
Show child attributes
versioninteger1required
mirror_listsbooleanrequired
updated_atstring<date-time> | null
objectsArray<IntegrationSyncObjectSelection>required
Show child attributes
object_idstring
object_slugstringrequired
labelstring
modestringaddressablerelatedrequired
enabledbooleantrue
field_policystringall_supportedselected
selected_fieldsArray<string>
excluded_fieldsArray<string>
relationshipobject
Show child attributes
attribute_slugstring
target_object_slugstringpeopleusers
trait_mappingIntegrationSyncTraitMapping
Show child attributes
kindstringdeal_pipelinerequired
stage_attributestringrequired
closed_stage_valuesArray<string>required
amount_attributestring
currency_attributestring
managed_audience_mapping_keystring
mirror_listsboolean
Example
{
  "sync_contract": {
    "version": 1,
    "mirror_lists": true,
    "updated_at": "2024-01-15T09:30:00Z",
    "objects": [
      {
        "object_id": "string",
        "object_slug": "string",
        "label": "string",
        "mode": "addressable",
        "enabled": true,
        "field_policy": "all_supported",
        "selected_fields": [
          "string"
        ],
        "excluded_fields": [
          "string"
        ],
        "relationship": {
          "attribute_slug": "string",
          "target_object_slug": "people"
        },
        "trait_mapping": {
          "kind": "deal_pipeline",
          "stage_attribute": "string",
          "closed_stage_values": [
            "string"
          ],
          "amount_attribute": "string",
          "currency_attribute": "string"
        },
        "managed_audience_mapping_key": "string",
        "mirror_lists": true
      }
    ]
  }
}

IntegrationSyncDiscovery

object
providerstringrequired
versioninteger1required
truncatedbooleanrequired
objectsArray<object>required
Show child attributes
object_idstringrequired
object_slugstringrequired
singular_nounstring
plural_nounstring
eligiblebooleanrequired
recommended_modestring | nulladdressablerelated
ineligible_reasonstring | null
attributes_truncatedboolean
attributesArray<IntegrationSyncDiscoveredAttribute>required
Show child attributes
attribute_idstringrequired
attribute_slugstringrequired
titlestring
typestringrequired
classificationstringcanonical_scalarfact_onlyrelationshiprequired
requiredboolean
uniqueboolean
multiselectboolean
target_object_slugsArray<string>
optionsArray<string>
relationship_attributesArray<IntegrationSyncDiscoveredAttribute>
Show child attributes
attribute_idstringrequired
attribute_slugstringrequired
titlestring
typestringrequired
classificationstringcanonical_scalarfact_onlyrelationshiprequired
requiredboolean
uniqueboolean
multiselectboolean
target_object_slugsArray<string>
optionsArray<string>
Example
{
  "provider": "string",
  "version": 1,
  "truncated": true,
  "objects": [
    {
      "object_id": "string",
      "object_slug": "string",
      "singular_noun": "string",
      "plural_noun": "string",
      "eligible": true,
      "recommended_mode": "addressable",
      "ineligible_reason": "string",
      "attributes_truncated": true,
      "attributes": [
        {
          "attribute_id": "string",
          "attribute_slug": "string",
          "title": "string",
          "type": "string",
          "classification": "canonical_scalar",
          "required": true,
          "unique": true,
          "multiselect": true,
          "target_object_slugs": [
            "string"
          ],
          "options": [
            "string"
          ]
        }
      ],
      "relationship_attributes": [
        {
          "attribute_id": "string",
          "attribute_slug": "string",
          "title": "string",
          "type": "string",
          "classification": "canonical_scalar",
          "required": true,
          "unique": true,
          "multiselect": true,
          "target_object_slugs": [
            "string"
          ],
          "options": [
            "string"
          ]
        }
      ]
    }
  ]
}

IntegrationSyncDiscoveredAttribute

object
attribute_idstringrequired
attribute_slugstringrequired
titlestring
typestringrequired
classificationstringcanonical_scalarfact_onlyrelationshiprequired
requiredboolean
uniqueboolean
multiselectboolean
target_object_slugsArray<string>
optionsArray<string>
Example
{
  "attribute_id": "string",
  "attribute_slug": "string",
  "title": "string",
  "type": "string",
  "classification": "canonical_scalar",
  "required": true,
  "unique": true,
  "multiselect": true,
  "target_object_slugs": [
    "string"
  ],
  "options": [
    "string"
  ]
}

MailgunIntegrationInput

object
providerstringmailgunrequired
api_keystringrequired
domainstringrequired

Mailgun sending domain

regionstring | null

Optional Mailgun region hint

activebooleantrue
Example
{
  "provider": "mailgun",
  "api_key": "string",
  "domain": "string",
  "region": "string",
  "active": true
}

SesIntegrationInput

object
providerstringsesrequired
access_key_idstringrequired
secret_access_keystringrequired
regionstringrequired

AWS SES region

activebooleantrue
Example
{
  "provider": "ses",
  "access_key_id": "string",
  "secret_access_key": "string",
  "region": "string",
  "active": true
}

PostmarkIntegrationInput

object
providerstringpostmarkrequired
server_tokenstringrequired

Postmark server token for sending email

account_tokenstringrequired

Postmark account token for domains API access

activebooleantrue
Example
{
  "provider": "postmark",
  "server_token": "string",
  "account_token": "string",
  "active": true
}

ResendIntegrationInput

object
providerstringresendrequired
api_keystringrequired
activebooleantrue
Example
{
  "provider": "resend",
  "api_key": "string",
  "active": true
}

SendgridIntegrationInput

object
providerstringsendgridrequired
api_keystringrequired
activebooleantrue
Example
{
  "provider": "sendgrid",
  "api_key": "string",
  "active": true
}

Plan

object
idinteger
namestring
activeboolean
probation_recipient_cap_24hinteger>= 0
standard_recipient_cap_24hinteger>= 0
trusted_recipient_cap_24hinteger>= 0

Full allowance on earning Trusted; zero represents a contracted unlimited allowance. Credits and safety remain separate.

entitlementsBillingEntitlements
Show child attributes
agent_inboxAgentInboxEntitlementrequired
Show child attributes
enabledbooleanrequired
max_inboxesinteger | null>= 0required

Account-wide exact-inbox capacity. Null means contract-defined unlimited capacity.

inbound_messages_includedinteger | null>= 0required
inbound_messages_meteredbooleanrequired
inbound_message_overage_rate_centsstringrequired
max_inbound_domainsinteger | null>= 0required
max_apex_domainsinteger | null>= 0required
apex_mxbooleanrequired
legacy_forwardingbooleanrequired
catch_allbooleanrequired
retention_daysinteger | null>= 0required
advanced_queue_controlsbooleanrequired
Example
{
  "id": 0,
  "name": "string",
  "active": true,
  "probation_recipient_cap_24h": 0,
  "standard_recipient_cap_24h": 0,
  "trusted_recipient_cap_24h": 0,
  "entitlements": {
    "agent_inbox": {
      "enabled": true,
      "max_inboxes": 0,
      "inbound_messages_included": 0,
      "inbound_messages_metered": true,
      "inbound_message_overage_rate_cents": "string",
      "max_inbound_domains": 0,
      "max_apex_domains": 0,
      "apex_mx": true,
      "legacy_forwarding": true,
      "catch_all": true,
      "retention_days": 0,
      "advanced_queue_controls": true
    }
  }
}

EmailDesign

object

Email template design document

versioninteger>= 1
sectionsArray<EmailSection>
Show child attributes
typestringheaderherotextimagebuttoncolumnsproductproductsgallerysocialdividerspacerfooterrequired
propsobject

Section-specific properties (see email component spec)

stylesobject
Show child attributes
background_colorstring
section_background_colorstring
paddingstring
alignstringleftcenterright
scalestringdisplayposter
font_sizeinteger
text_colorstring
shapestringsquareroundedarchcircle
remove_gapboolean
border_radiusinteger
themeobject

Theme overrides merged on top of brand theme

Show child attributes
brand_colorstring
bg_colorstring
text_colorstring
font_bodystring
font_headingstring
heading_sizeinteger
body_sizeinteger
radiusinteger
spacing_densitystringcompactnormalspacious
button_background_colorstring
button_text_colorstring
button_paddingstring
logo_urlstring
company_namestring
physical_addressstring
social_linksArray<object>
Show child attributes
platformstring
urlstring
Example
{
  "version": 1,
  "sections": [
    {
      "type": "header",
      "props": {},
      "styles": {
        "background_color": "string",
        "section_background_color": "string",
        "padding": "string",
        "align": "left",
        "scale": "display",
        "font_size": 0,
        "text_color": "string",
        "shape": "square",
        "remove_gap": true,
        "border_radius": 0
      }
    }
  ],
  "theme": {
    "brand_color": "string",
    "bg_color": "string",
    "text_color": "string",
    "font_body": "string",
    "font_heading": "string",
    "heading_size": 0,
    "body_size": 0,
    "radius": 0,
    "spacing_density": "compact",
    "button_background_color": "string",
    "button_text_color": "string",
    "button_padding": "string",
    "logo_url": "string",
    "company_name": "string",
    "physical_address": "string",
    "social_links": [
      {
        "platform": "string",
        "url": "string"
      }
    ]
  }
}

EmailAccessibilityLint

object

Advisory accessibility lint result for rendered email previews

validboolean

Always true while accessibility lint is advisory-only

warningsArray<EmailAccessibilityWarning>
Show child attributes
levelstring
rulestring
messagestring
suggested_fixstring
countinteger
min_rationumber<float>
Example
{
  "valid": true,
  "warnings": [
    {
      "level": "warning",
      "rule": "image_alt_text",
      "message": "string",
      "suggested_fix": "string",
      "count": 0,
      "min_ratio": 0
    }
  ]
}

EmailAccessibilityWarning

object
levelstring
rulestring
messagestring
suggested_fixstring
countinteger
min_rationumber<float>
Example
{
  "level": "warning",
  "rule": "image_alt_text",
  "message": "string",
  "suggested_fix": "string",
  "count": 0,
  "min_ratio": 0
}

EmailSection

object
typestringheaderherotextimagebuttoncolumnsproductproductsgallerysocialdividerspacerfooterrequired
propsobject

Section-specific properties (see email component spec)

stylesobject
Show child attributes
background_colorstring
section_background_colorstring
paddingstring
alignstringleftcenterright
scalestringdisplayposter
font_sizeinteger
text_colorstring
shapestringsquareroundedarchcircle
remove_gapboolean
border_radiusinteger
Example
{
  "type": "header",
  "props": {},
  "styles": {
    "background_color": "string",
    "section_background_color": "string",
    "padding": "string",
    "align": "left",
    "scale": "display",
    "font_size": 0,
    "text_color": "string",
    "shape": "square",
    "remove_gap": true,
    "border_radius": 0
  }
}

EmailComponentSpec

object

Full schema for email design sections. Each component has type, description, props (with types, required flags, defaults), and tips.

versionintegerrequired
design_guidelinesstringrequired
componentsArray<object>required
Show child attributes
typestringrequired
descriptionstringrequired
tipsArray<string>
propsobjectrequired
style_attributesArray<object>required

Standard per-section style attribute registry.

Show child attributes
keystringrequired
labelstringrequired
typestringcolorspacingenumnumberbooleanrequired
applies_toanyrequired
defaultany
theme_fallbackstring
descriptionstringrequired
mininteger
maxinteger
valuesArray<string>
targetobjectrequired
Show child attributes
elstringsectioncontentshaperequired
attrstring
preview_documentobjectrequired
Show child attributes
parameterstringrequired
descriptionstringrequired
exampleobjectrequired
variablesobjectrequired

Merge variables grouped by source namespace.

filtersArray<object>required
Show child attributes
namestringrequired
syntaxstringrequired
descriptionstringrequired
theme_attributesArray<object>required

Brand Kit theme attribute registry (single source of truth for the editor).

Show child attributes
keystringrequired
labelstringrequired
typestringcolorfontnumberenumspacingstringimagearrayrequired
defaultany
categorystringcolorfontvisual_identityidentityrequired
slotstring
surfacesArray<string>required
mininteger
maxinteger
valuesArray<string>
optionsArray<object>
Show child attributes
valuestring
labelstring
descriptionstring
transform_tableobject
columnboolean
storagestring
placeholderstring
value_resolverstring
server_ownedboolean
descriptionstring
Example
{
  "version": 0,
  "design_guidelines": "string",
  "components": [
    {
      "type": "string",
      "description": "string",
      "tips": [
        "string"
      ],
      "props": {}
    }
  ],
  "style_attributes": [
    {
      "key": "string",
      "label": "string",
      "type": "color",
      "theme_fallback": "string",
      "description": "string",
      "min": 0,
      "max": 0,
      "values": [
        "string"
      ],
      "target": {
        "el": "section",
        "attr": "string"
      }
    }
  ],
  "preview_document": {
    "parameter": "string",
    "description": "string",
    "example": {}
  },
  "variables": {},
  "filters": [
    {
      "name": "string",
      "syntax": "string",
      "description": "string"
    }
  ],
  "theme_attributes": [
    {
      "key": "string",
      "label": "string",
      "type": "color",
      "category": "color",
      "slot": "string",
      "surfaces": [
        "string"
      ],
      "min": 0,
      "max": 0,
      "values": [
        "string"
      ],
      "options": [
        {
          "value": "string",
          "label": "string",
          "description": "string"
        }
      ],
      "transform_table": {},
      "column": true,
      "storage": "string",
      "placeholder": "string",
      "value_resolver": "string",
      "server_owned": true,
      "description": "string"
    }
  ]
}

FlowSpec

object

Schema for flow step types, trigger events, and segment filter names. Note: the raw response includes internal fields (icon, visible, inputs, outputs, alias) used by the flow editor UI — these can be ignored by API consumers.

filtersobject
triggersArray<object>
Show child attributes
titlestring
eventstring
stepsArray<object>
Show child attributes
typestring
titlestring
summarystring
paramsobject
lifecycle_flowsArray<object>

Canonical lifecycle flow templates for the flow picker.

Show child attributes
idstring
keystring
goalstring
namestring
descriptionstring
priorityinteger
triggerobject
Show child attributes
eventstring
trigger_needsstring | null
stepsArray<object>
Show child attributes
typestring
durationinteger

Wait duration in seconds for wait steps.

subjectstring
preheaderstring
bodystring
designobject
Example
{
  "filters": {},
  "triggers": [
    {
      "title": "string",
      "event": "string"
    }
  ],
  "steps": [
    {
      "type": "string",
      "title": "string",
      "summary": "string",
      "params": {}
    }
  ],
  "lifecycle_flows": [
    {
      "id": "string",
      "key": "string",
      "goal": "string",
      "name": "string",
      "description": "string",
      "priority": 0,
      "trigger": {
        "event": "string"
      },
      "trigger_needs": "string",
      "steps": [
        {
          "type": "string",
          "duration": 0,
          "subject": "string",
          "preheader": "string",
          "body": "string",
          "design": {}
        }
      ]
    }
  ]
}