Notification library

7 endpoints

Notifications as reusable content, placed on any number of campaigns. With campaign placements on for the workspace only: these endpoints 404 otherwise.

List library notifications#

GET/notifications
Needs notifications:read

Query parameters

cursor
string

An opaque value from a previous page's meta.next_cursor. Omit for the first page.

limit
integer

How many to return, up to 100.

Default: 20
updated_since
string (date-time)

Only notifications updated at or after this ISO 8601 timestamp.

archived
boolean

true lists the archived notifications instead of the others.

Default: false

Responses

200
200 response
{
  "data": [
    {
      "id": "0192f0a4-6b1e-7c3a-9d2f-5e8b1a4d5001",
      "name": "Morning flat white offer",
      "type": "message",
      "headline": "Coffee's on us",
      "body": "Show this at the counter for a free flat white before 11am.",
      "media": null,
      "cta_label": "Get the voucher",
      "cta_url": "https://example.com/offers/flat-white",
      "questions": [],
      "created_at": "2026-09-20T09:12:00+00:00",
      "updated_at": "2026-09-20T09:12:00+00:00",
      "archived_at": null
    }
  ],
  "meta": {
    "next_cursor": null
  }
}
Response fields
data
NotificationResource[]
required
data[].id
string
required
data[].name
string
required
data[].type
string
required
data[].headline
string
required
data[].body
string
required
data[].media
object | null
data[].media.id
string
required
data[].media.url
string | null
required
data[].media.type
string
required
data[].cta_label
string | null
required
data[].cta_url
string | null
required
data[].questions
NotificationQuestionResource[]
data[].questions[].id
string
required
data[].questions[].question_text
string
required
data[].questions[].type
string
required
data[].questions[].required
boolean
required
data[].questions[].choices
string[]
data[].archived_at
string | null
required

Archived: it keeps running where it is placed but can't be placed again until unarchived.

data[].created_at
string | null
required
data[].updated_at
string | null
required
meta
object
required
meta.next_cursor
string | null
required
401

The token is missing, unknown, revoked or expired.

missing_tokeninvalid_tokentoken_revokedtoken_expired
  • missing_token

    Missing bearer token.

  • invalid_token

    Unknown API token. Check it was copied in full, and that it is for this environment.

  • token_revoked

    The token "Zapier" was revoked on 2026-10-06 at 18:27 UTC. Issue a new one from Configuration › Platform API.

  • token_expired

    This token has expired. Issue a new one from Configuration › Platform API.

401 response
{
  "error": {
    "code": "missing_token",
    "message": "Missing bearer token."
  }
}
403

The token or workspace can't do this.

missing_abilityplatform_api_not_enabledwrong_environmentworkspace_pausedsandbox_unavailable
  • missing_ability

    This token doesn't have the campaigns:write scope.

  • platform_api_not_enabled

    The full Platform API isn't enabled for this workspace yet. Contact customer services to turn it on.

  • wrong_environment

    This is a Sandbox token: use the Sandbox API address. https://api.sandbox.bubbl.tech/platform/v1

  • workspace_paused

    This workspace is scheduled for deletion; its API access is paused.

  • sandbox_unavailable

    The Sandbox isn't available for this workspace.

403 response
{
  "error": {
    "code": "missing_ability",
    "message": "This token doesn't have the campaigns:write scope."
  }
}
422

Something in the request isn't valid. fields says what, with the dashboard's wording.

invalid_parameterinvalid_cursor
  • invalid_parameter

    updated_since must be a valid date.

  • invalid_cursor

    That cursor is invalid or has expired.

422 response
{
  "error": {
    "code": "invalid_parameter",
    "message": "updated_since must be a valid date.",
    "fields": {
      "updated_since": [
        "Must be a valid date."
      ]
    }
  }
}
429

Too many requests. Wait for the number of seconds in Retry-After.

rate_limitedtoo_many_failed_attempts
  • rate_limited

    Too many requests. Slow down and try again shortly.

  • too_many_failed_attempts

    Too many failed attempts. Try again shortly.

429 response
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Slow down and try again shortly."
  }
}
Request
curl 'https://api.bubbl.tech/platform/v1/notifications?limit=20' \
  -H 'Authorization: Bearer bubbl_YOUR_TOKEN' \
  -H 'Accept: application/json'
Request
const response = await fetch('https://api.bubbl.tech/platform/v1/notifications?limit=20', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer bubbl_YOUR_TOKEN',
    Accept: 'application/json',
  },
});

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

response = requests.request(
    'GET',
    'https://api.bubbl.tech/platform/v1/notifications?limit=20',
    headers={
        'Authorization': 'Bearer bubbl_YOUR_TOKEN',
        'Accept': 'application/json',
    },
)
response.raise_for_status()
data = response.json()
Request
<?php

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.bubbl.tech/platform/v1/notifications?limit=20', [
    'headers' => [
        'Authorization' => 'Bearer bubbl_YOUR_TOKEN',
        'Accept' => 'application/json',
    ],
]);

$data = json_decode((string) $response->getBody(), true);

Create a library notification#

POST/notifications
Needs notifications:write

Its content alone, with the same rules as adding one to a campaign; place it on campaigns with its notification_id. Counts towards the plan's notification limit.

Headers

Idempotency-Key
string

A unique value (e.g. a UUID) for this change. A retry with the same key within 24 hours gets the first response back, with Idempotent-Replayed: true, instead of making the change again.

Request body

application/jsonStoreNotificationRequestrequired
name
string
required
type
string
required
One of: message, survey
headline
string
required
body
string
required
media_asset_id
string (uuid) | null
cta_label
string | null
cta_url
string (uri) | null
questions
object[]
required
questions[].id
string (uuid) | null
questions[].question_text
string
required
questions[].type
string
required
One of: OPEN_ENDED, SINGLE_CHOICE, MULTIPLE_CHOICE, RATING, BOOLEAN, NUMBER, SLIDER
questions[].required
boolean
questions[].choices
object[]
questions[].choices[].id
string (uuid) | null
questions[].choices[].text
string
required

Responses

201
201 response
{
  "data": {
    "id": "0192f0a4-6b1e-7c3a-9d2f-5e8b1a4d5001",
    "name": "Morning flat white offer",
    "type": "message",
    "headline": "Coffee's on us",
    "body": "Show this at the counter for a free flat white before 11am.",
    "media": null,
    "cta_label": "Get the voucher",
    "cta_url": "https://example.com/offers/flat-white",
    "questions": [],
    "created_at": "2026-09-20T09:12:00+00:00",
    "updated_at": "2026-09-20T09:12:00+00:00",
    "archived_at": null
  }
}
Response fields
data
object
required
data.id
string
required
data.name
string
required
data.type
string
required
data.headline
string
required
data.body
string
required
data.media
object | null
required
data.media.id
string
required
data.media.url
string | null
required
data.media.type
string
required
data.cta_label
string | null
required
data.cta_url
string | null
required
data.questions
NotificationQuestionResource[]
required
data.questions[].id
string
required
data.questions[].question_text
string
required
data.questions[].type
string
required
data.questions[].required
boolean
required
data.questions[].choices
string[]
data.archived_at
string | null
required

Archived: it keeps running where it is placed but can't be placed again until unarchived.

data.created_at
string | null
required
data.updated_at
string | null
required
401

The token is missing, unknown, revoked or expired.

missing_tokeninvalid_tokentoken_revokedtoken_expired
  • missing_token

    Missing bearer token.

  • invalid_token

    Unknown API token. Check it was copied in full, and that it is for this environment.

  • token_revoked

    The token "Zapier" was revoked on 2026-10-06 at 18:27 UTC. Issue a new one from Configuration › Platform API.

  • token_expired

    This token has expired. Issue a new one from Configuration › Platform API.

401 response
{
  "error": {
    "code": "missing_token",
    "message": "Missing bearer token."
  }
}
403

The token or workspace can't do this.

missing_abilityplatform_api_not_enabledwrong_environmentworkspace_pausedsandbox_unavailablelimit_exceeded
  • missing_ability

    This token doesn't have the campaigns:write scope.

  • platform_api_not_enabled

    The full Platform API isn't enabled for this workspace yet. Contact customer services to turn it on.

  • wrong_environment

    This is a Sandbox token: use the Sandbox API address. https://api.sandbox.bubbl.tech/platform/v1

  • workspace_paused

    This workspace is scheduled for deletion; its API access is paused.

  • sandbox_unavailable

    The Sandbox isn't available for this workspace.

  • limit_exceeded

    You've reached the limit for max_campaigns.

403 response
{
  "error": {
    "code": "missing_ability",
    "message": "This token doesn't have the campaigns:write scope."
  }
}
409

A request with the same Idempotency-Key is still running (retry after Retry-After seconds), or the change conflicts with something that depends on it.

request_in_progress
  • request_in_progress

    This request is still being handled. Try again shortly.

409 response
{
  "error": {
    "code": "request_in_progress",
    "message": "This request is still being handled. Try again shortly."
  }
}
422

Something in the request isn't valid. fields says what, with the dashboard's wording.

validation_failed
  • validation_failed

    The given data was invalid.

422 response
{
  "error": {
    "code": "validation_failed",
    "message": "The given data was invalid.",
    "fields": {
      "name": [
        "The name field is required."
      ]
    }
  }
}
429

Too many requests. Wait for the number of seconds in Retry-After.

rate_limitedtoo_many_failed_attempts
  • rate_limited

    Too many requests. Slow down and try again shortly.

  • too_many_failed_attempts

    Too many failed attempts. Try again shortly.

429 response
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Slow down and try again shortly."
  }
}
Request
curl -X POST 'https://api.bubbl.tech/platform/v1/notifications' \
  -H 'Authorization: Bearer bubbl_YOUR_TOKEN' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  --data '{
  "name": "Morning flat white offer",
  "type": "message",
  "headline": "Coffee'\''s on us",
  "body": "Show this at the counter for a free flat white before 11am.",
  "cta_label": "Get the voucher",
  "cta_url": "https://example.com/offers/flat-white"
}'
Request
const response = await fetch('https://api.bubbl.tech/platform/v1/notifications', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer bubbl_YOUR_TOKEN',
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Morning flat white offer',
    type: 'message',
    headline: 'Coffee\'s on us',
    body: 'Show this at the counter for a free flat white before 11am.',
    cta_label: 'Get the voucher',
    cta_url: 'https://example.com/offers/flat-white',
  }),
});

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

response = requests.request(
    'POST',
    'https://api.bubbl.tech/platform/v1/notifications',
    headers={
        'Authorization': 'Bearer bubbl_YOUR_TOKEN',
        'Accept': 'application/json',
        'Content-Type': 'application/json',
    },
    json={
        'name': 'Morning flat white offer',
        'type': 'message',
        'headline': 'Coffee\'s on us',
        'body': 'Show this at the counter for a free flat white before 11am.',
        'cta_label': 'Get the voucher',
        'cta_url': 'https://example.com/offers/flat-white',
    },
)
response.raise_for_status()
data = response.json()
Request
<?php

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.bubbl.tech/platform/v1/notifications', [
    'headers' => [
        'Authorization' => 'Bearer bubbl_YOUR_TOKEN',
        'Accept' => 'application/json',
        'Content-Type' => 'application/json',
    ],
    'json' => [
        'name' => 'Morning flat white offer',
        'type' => 'message',
        'headline' => 'Coffee\'s on us',
        'body' => 'Show this at the counter for a free flat white before 11am.',
        'cta_label' => 'Get the voucher',
        'cta_url' => 'https://example.com/offers/flat-white',
    ],
]);

$data = json_decode((string) $response->getBody(), true);

Get a library notification#

GET/notifications/{notification}
Needs notifications:read

Path parameters

notification
string (uuid)
required

The notification ID

Responses

200
200 response
{
  "data": {
    "id": "0192f0a4-6b1e-7c3a-9d2f-5e8b1a4d5001",
    "name": "Morning flat white offer",
    "type": "message",
    "headline": "Coffee's on us",
    "body": "Show this at the counter for a free flat white before 11am.",
    "media": null,
    "cta_label": "Get the voucher",
    "cta_url": "https://example.com/offers/flat-white",
    "questions": [],
    "created_at": "2026-09-20T09:12:00+00:00",
    "updated_at": "2026-09-20T09:12:00+00:00",
    "archived_at": null
  }
}
Response fields
data
object
required
data.id
string
required
data.name
string
required
data.type
string
required
data.headline
string
required
data.body
string
required
data.media
object | null
required
data.media.id
string
required
data.media.url
string | null
required
data.media.type
string
required
data.cta_label
string | null
required
data.cta_url
string | null
required
data.questions
NotificationQuestionResource[]
required
data.questions[].id
string
required
data.questions[].question_text
string
required
data.questions[].type
string
required
data.questions[].required
boolean
required
data.questions[].choices
string[]
data.archived_at
string | null
required

Archived: it keeps running where it is placed but can't be placed again until unarchived.

data.created_at
string | null
required
data.updated_at
string | null
required
401

The token is missing, unknown, revoked or expired.

missing_tokeninvalid_tokentoken_revokedtoken_expired
  • missing_token

    Missing bearer token.

  • invalid_token

    Unknown API token. Check it was copied in full, and that it is for this environment.

  • token_revoked

    The token "Zapier" was revoked on 2026-10-06 at 18:27 UTC. Issue a new one from Configuration › Platform API.

  • token_expired

    This token has expired. Issue a new one from Configuration › Platform API.

401 response
{
  "error": {
    "code": "missing_token",
    "message": "Missing bearer token."
  }
}
403

The token or workspace can't do this.

missing_abilityplatform_api_not_enabledwrong_environmentworkspace_pausedsandbox_unavailable
  • missing_ability

    This token doesn't have the campaigns:write scope.

  • platform_api_not_enabled

    The full Platform API isn't enabled for this workspace yet. Contact customer services to turn it on.

  • wrong_environment

    This is a Sandbox token: use the Sandbox API address. https://api.sandbox.bubbl.tech/platform/v1

  • workspace_paused

    This workspace is scheduled for deletion; its API access is paused.

  • sandbox_unavailable

    The Sandbox isn't available for this workspace.

403 response
{
  "error": {
    "code": "missing_ability",
    "message": "This token doesn't have the campaigns:write scope."
  }
}
404

Nothing with that ID in this workspace.

not_found
  • not_found

    No such resource in this workspace.

404 response
{
  "error": {
    "code": "not_found",
    "message": "No such resource in this workspace."
  }
}
429

Too many requests. Wait for the number of seconds in Retry-After.

rate_limitedtoo_many_failed_attempts
  • rate_limited

    Too many requests. Slow down and try again shortly.

  • too_many_failed_attempts

    Too many failed attempts. Try again shortly.

429 response
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Slow down and try again shortly."
  }
}
Request
curl 'https://api.bubbl.tech/platform/v1/notifications/{notification}' \
  -H 'Authorization: Bearer bubbl_YOUR_TOKEN' \
  -H 'Accept: application/json'
Request
const response = await fetch('https://api.bubbl.tech/platform/v1/notifications/{notification}', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer bubbl_YOUR_TOKEN',
    Accept: 'application/json',
  },
});

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

response = requests.request(
    'GET',
    'https://api.bubbl.tech/platform/v1/notifications/{notification}',
    headers={
        'Authorization': 'Bearer bubbl_YOUR_TOKEN',
        'Accept': 'application/json',
    },
)
response.raise_for_status()
data = response.json()
Request
<?php

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.bubbl.tech/platform/v1/notifications/{notification}', [
    'headers' => [
        'Authorization' => 'Bearer bubbl_YOUR_TOKEN',
        'Accept' => 'application/json',
    ],
]);

$data = json_decode((string) $response->getBody(), true);

Update a library notification#

PATCH/notifications/{notification}
Needs notifications:write

The whole content is resubmitted. It changes on every campaign the notification is placed on.

Path parameters

notification
string (uuid)
required

The notification ID

Headers

Idempotency-Key
string

A unique value (e.g. a UUID) for this change. A retry with the same key within 24 hours gets the first response back, with Idempotent-Replayed: true, instead of making the change again.

Request body

application/jsonUpdateNotificationRequestrequired
name
string
required
type
string
required
One of: message, survey
headline
string
required
body
string
required
media_asset_id
string (uuid) | null
cta_label
string | null
cta_url
string (uri) | null
questions
object[]
required
questions[].id
string (uuid) | null
questions[].question_text
string
required
questions[].type
string
required
One of: OPEN_ENDED, SINGLE_CHOICE, MULTIPLE_CHOICE, RATING, BOOLEAN, NUMBER, SLIDER
questions[].required
boolean
questions[].choices
object[]
questions[].choices[].id
string (uuid) | null
questions[].choices[].text
string
required

Responses

200
200 response
{
  "data": {
    "id": "0192f0a4-6b1e-7c3a-9d2f-5e8b1a4d5001",
    "name": "Morning flat white offer",
    "type": "message",
    "headline": "Two coffees for one",
    "body": "Show this at the counter for a free flat white before 11am.",
    "media": null,
    "cta_label": "Get the voucher",
    "cta_url": "https://example.com/offers/flat-white",
    "questions": [],
    "created_at": "2026-09-20T09:12:00+00:00",
    "updated_at": "2026-09-20T09:12:00+00:00",
    "archived_at": null
  }
}
Response fields
data
object
required
data.id
string
required
data.name
string
required
data.type
string
required
data.headline
string
required
data.body
string
required
data.media
object | null
required
data.media.id
string
required
data.media.url
string | null
required
data.media.type
string
required
data.cta_label
string | null
required
data.cta_url
string | null
required
data.questions
NotificationQuestionResource[]
required
data.questions[].id
string
required
data.questions[].question_text
string
required
data.questions[].type
string
required
data.questions[].required
boolean
required
data.questions[].choices
string[]
data.archived_at
string | null
required

Archived: it keeps running where it is placed but can't be placed again until unarchived.

data.created_at
string | null
required
data.updated_at
string | null
required
401

The token is missing, unknown, revoked or expired.

missing_tokeninvalid_tokentoken_revokedtoken_expired
  • missing_token

    Missing bearer token.

  • invalid_token

    Unknown API token. Check it was copied in full, and that it is for this environment.

  • token_revoked

    The token "Zapier" was revoked on 2026-10-06 at 18:27 UTC. Issue a new one from Configuration › Platform API.

  • token_expired

    This token has expired. Issue a new one from Configuration › Platform API.

401 response
{
  "error": {
    "code": "missing_token",
    "message": "Missing bearer token."
  }
}
403

The token or workspace can't do this.

missing_abilityplatform_api_not_enabledwrong_environmentworkspace_pausedsandbox_unavailable
  • missing_ability

    This token doesn't have the campaigns:write scope.

  • platform_api_not_enabled

    The full Platform API isn't enabled for this workspace yet. Contact customer services to turn it on.

  • wrong_environment

    This is a Sandbox token: use the Sandbox API address. https://api.sandbox.bubbl.tech/platform/v1

  • workspace_paused

    This workspace is scheduled for deletion; its API access is paused.

  • sandbox_unavailable

    The Sandbox isn't available for this workspace.

403 response
{
  "error": {
    "code": "missing_ability",
    "message": "This token doesn't have the campaigns:write scope."
  }
}
404

Nothing with that ID in this workspace.

not_found
  • not_found

    No such resource in this workspace.

404 response
{
  "error": {
    "code": "not_found",
    "message": "No such resource in this workspace."
  }
}
409

A request with the same Idempotency-Key is still running (retry after Retry-After seconds), or the change conflicts with something that depends on it.

request_in_progress
  • request_in_progress

    This request is still being handled. Try again shortly.

409 response
{
  "error": {
    "code": "request_in_progress",
    "message": "This request is still being handled. Try again shortly."
  }
}
422

Something in the request isn't valid. fields says what, with the dashboard's wording.

validation_failed
  • validation_failed

    The given data was invalid.

422 response
{
  "error": {
    "code": "validation_failed",
    "message": "The given data was invalid.",
    "fields": {
      "name": [
        "The name field is required."
      ]
    }
  }
}
429

Too many requests. Wait for the number of seconds in Retry-After.

rate_limitedtoo_many_failed_attempts
  • rate_limited

    Too many requests. Slow down and try again shortly.

  • too_many_failed_attempts

    Too many failed attempts. Try again shortly.

429 response
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Slow down and try again shortly."
  }
}
Request
curl -X PATCH 'https://api.bubbl.tech/platform/v1/notifications/{notification}' \
  -H 'Authorization: Bearer bubbl_YOUR_TOKEN' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  --data '{
  "name": "Morning flat white offer",
  "type": "message",
  "headline": "Two coffees for one",
  "body": "Show this at the counter for a free flat white before 11am.",
  "cta_label": "Get the voucher",
  "cta_url": "https://example.com/offers/flat-white"
}'
Request
const response = await fetch('https://api.bubbl.tech/platform/v1/notifications/{notification}', {
  method: 'PATCH',
  headers: {
    Authorization: 'Bearer bubbl_YOUR_TOKEN',
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Morning flat white offer',
    type: 'message',
    headline: 'Two coffees for one',
    body: 'Show this at the counter for a free flat white before 11am.',
    cta_label: 'Get the voucher',
    cta_url: 'https://example.com/offers/flat-white',
  }),
});

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

response = requests.request(
    'PATCH',
    'https://api.bubbl.tech/platform/v1/notifications/{notification}',
    headers={
        'Authorization': 'Bearer bubbl_YOUR_TOKEN',
        'Accept': 'application/json',
        'Content-Type': 'application/json',
    },
    json={
        'name': 'Morning flat white offer',
        'type': 'message',
        'headline': 'Two coffees for one',
        'body': 'Show this at the counter for a free flat white before 11am.',
        'cta_label': 'Get the voucher',
        'cta_url': 'https://example.com/offers/flat-white',
    },
)
response.raise_for_status()
data = response.json()
Request
<?php

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://api.bubbl.tech/platform/v1/notifications/{notification}', [
    'headers' => [
        'Authorization' => 'Bearer bubbl_YOUR_TOKEN',
        'Accept' => 'application/json',
        'Content-Type' => 'application/json',
    ],
    'json' => [
        'name' => 'Morning flat white offer',
        'type' => 'message',
        'headline' => 'Two coffees for one',
        'body' => 'Show this at the counter for a free flat white before 11am.',
        'cta_label' => 'Get the voucher',
        'cta_url' => 'https://example.com/offers/flat-white',
    ],
]);

$data = json_decode((string) $response->getBody(), true);

Delete a library notification#

DELETE/notifications/{notification}
Needs notifications:write

Refused (409 notification_in_use) while it is placed on a campaign; used_in lists them. Remove it from them first, or archive it instead.

Path parameters

notification
string (uuid)
required

The notification ID

Headers

Idempotency-Key
string

A unique value (e.g. a UUID) for this change. A retry with the same key within 24 hours gets the first response back, with Idempotent-Replayed: true, instead of making the change again.

Responses

200
200 response
{
  "data": {
    "id": "0192f0a4-6b1e-7c3a-9d2f-5e8b1a4d5001",
    "deleted": true
  }
}
Response fields
data
object
required
data.id
string
required
data.deleted
boolean
required
401

The token is missing, unknown, revoked or expired.

missing_tokeninvalid_tokentoken_revokedtoken_expired
  • missing_token

    Missing bearer token.

  • invalid_token

    Unknown API token. Check it was copied in full, and that it is for this environment.

  • token_revoked

    The token "Zapier" was revoked on 2026-10-06 at 18:27 UTC. Issue a new one from Configuration › Platform API.

  • token_expired

    This token has expired. Issue a new one from Configuration › Platform API.

401 response
{
  "error": {
    "code": "missing_token",
    "message": "Missing bearer token."
  }
}
403

The token or workspace can't do this.

missing_abilityplatform_api_not_enabledwrong_environmentworkspace_pausedsandbox_unavailable
  • missing_ability

    This token doesn't have the campaigns:write scope.

  • platform_api_not_enabled

    The full Platform API isn't enabled for this workspace yet. Contact customer services to turn it on.

  • wrong_environment

    This is a Sandbox token: use the Sandbox API address. https://api.sandbox.bubbl.tech/platform/v1

  • workspace_paused

    This workspace is scheduled for deletion; its API access is paused.

  • sandbox_unavailable

    The Sandbox isn't available for this workspace.

403 response
{
  "error": {
    "code": "missing_ability",
    "message": "This token doesn't have the campaigns:write scope."
  }
}
404

Nothing with that ID in this workspace.

not_found
  • not_found

    No such resource in this workspace.

404 response
{
  "error": {
    "code": "not_found",
    "message": "No such resource in this workspace."
  }
}
409

A request with the same Idempotency-Key is still running (retry after Retry-After seconds), or the change conflicts with something that depends on it.

request_in_progressnotification_in_use
  • request_in_progress

    This request is still being handled. Try again shortly.

  • notification_in_use

    Campaigns use this notification; remove it from them first, or archive it instead.

409 response
{
  "error": {
    "code": "request_in_progress",
    "message": "This request is still being handled. Try again shortly."
  }
}
429

Too many requests. Wait for the number of seconds in Retry-After.

rate_limitedtoo_many_failed_attempts
  • rate_limited

    Too many requests. Slow down and try again shortly.

  • too_many_failed_attempts

    Too many failed attempts. Try again shortly.

429 response
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Slow down and try again shortly."
  }
}
Request
curl -X DELETE 'https://api.bubbl.tech/platform/v1/notifications/{notification}' \
  -H 'Authorization: Bearer bubbl_YOUR_TOKEN' \
  -H 'Accept: application/json'
Request
const response = await fetch('https://api.bubbl.tech/platform/v1/notifications/{notification}', {
  method: 'DELETE',
  headers: {
    Authorization: 'Bearer bubbl_YOUR_TOKEN',
    Accept: 'application/json',
  },
});

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

response = requests.request(
    'DELETE',
    'https://api.bubbl.tech/platform/v1/notifications/{notification}',
    headers={
        'Authorization': 'Bearer bubbl_YOUR_TOKEN',
        'Accept': 'application/json',
    },
)
response.raise_for_status()
data = response.json()
Request
<?php

$client = new \GuzzleHttp\Client();

$response = $client->request('DELETE', 'https://api.bubbl.tech/platform/v1/notifications/{notification}', [
    'headers' => [
        'Authorization' => 'Bearer bubbl_YOUR_TOKEN',
        'Accept' => 'application/json',
    ],
]);

$data = json_decode((string) $response->getBody(), true);

Archive a library notification#

POST/notifications/{notification}/archive
Needs notifications:write

Path parameters

notification
string (uuid)
required

The notification ID

Headers

Idempotency-Key
string

A unique value (e.g. a UUID) for this change. A retry with the same key within 24 hours gets the first response back, with Idempotent-Replayed: true, instead of making the change again.

Responses

200
200 response
{
  "data": {
    "id": "0192f0a4-6b1e-7c3a-9d2f-5e8b1a4d5001",
    "name": "Morning flat white offer",
    "type": "message",
    "headline": "Coffee's on us",
    "body": "Show this at the counter for a free flat white before 11am.",
    "media": null,
    "cta_label": "Get the voucher",
    "cta_url": "https://example.com/offers/flat-white",
    "questions": [],
    "created_at": "2026-09-20T09:12:00+00:00",
    "updated_at": "2026-09-20T09:12:00+00:00",
    "archived_at": "2026-10-31T17:00:00+00:00"
  }
}
Response fields
data
object
required
data.id
string
required
data.name
string
required
data.type
string
required
data.headline
string
required
data.body
string
required
data.media
object | null
required
data.media.id
string
required
data.media.url
string | null
required
data.media.type
string
required
data.cta_label
string | null
required
data.cta_url
string | null
required
data.questions
NotificationQuestionResource[]
required
data.questions[].id
string
required
data.questions[].question_text
string
required
data.questions[].type
string
required
data.questions[].required
boolean
required
data.questions[].choices
string[]
data.archived_at
string | null
required

Archived: it keeps running where it is placed but can't be placed again until unarchived.

data.created_at
string | null
required
data.updated_at
string | null
required
401

The token is missing, unknown, revoked or expired.

missing_tokeninvalid_tokentoken_revokedtoken_expired
  • missing_token

    Missing bearer token.

  • invalid_token

    Unknown API token. Check it was copied in full, and that it is for this environment.

  • token_revoked

    The token "Zapier" was revoked on 2026-10-06 at 18:27 UTC. Issue a new one from Configuration › Platform API.

  • token_expired

    This token has expired. Issue a new one from Configuration › Platform API.

401 response
{
  "error": {
    "code": "missing_token",
    "message": "Missing bearer token."
  }
}
403

The token or workspace can't do this.

missing_abilityplatform_api_not_enabledwrong_environmentworkspace_pausedsandbox_unavailable
  • missing_ability

    This token doesn't have the campaigns:write scope.

  • platform_api_not_enabled

    The full Platform API isn't enabled for this workspace yet. Contact customer services to turn it on.

  • wrong_environment

    This is a Sandbox token: use the Sandbox API address. https://api.sandbox.bubbl.tech/platform/v1

  • workspace_paused

    This workspace is scheduled for deletion; its API access is paused.

  • sandbox_unavailable

    The Sandbox isn't available for this workspace.

403 response
{
  "error": {
    "code": "missing_ability",
    "message": "This token doesn't have the campaigns:write scope."
  }
}
404

Nothing with that ID in this workspace.

not_found
  • not_found

    No such resource in this workspace.

404 response
{
  "error": {
    "code": "not_found",
    "message": "No such resource in this workspace."
  }
}
409

A request with the same Idempotency-Key is still running (retry after Retry-After seconds), or the change conflicts with something that depends on it.

request_in_progress
  • request_in_progress

    This request is still being handled. Try again shortly.

409 response
{
  "error": {
    "code": "request_in_progress",
    "message": "This request is still being handled. Try again shortly."
  }
}
429

Too many requests. Wait for the number of seconds in Retry-After.

rate_limitedtoo_many_failed_attempts
  • rate_limited

    Too many requests. Slow down and try again shortly.

  • too_many_failed_attempts

    Too many failed attempts. Try again shortly.

429 response
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Slow down and try again shortly."
  }
}
Request
curl -X POST 'https://api.bubbl.tech/platform/v1/notifications/{notification}/archive' \
  -H 'Authorization: Bearer bubbl_YOUR_TOKEN' \
  -H 'Accept: application/json'
Request
const response = await fetch('https://api.bubbl.tech/platform/v1/notifications/{notification}/archive', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer bubbl_YOUR_TOKEN',
    Accept: 'application/json',
  },
});

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

response = requests.request(
    'POST',
    'https://api.bubbl.tech/platform/v1/notifications/{notification}/archive',
    headers={
        'Authorization': 'Bearer bubbl_YOUR_TOKEN',
        'Accept': 'application/json',
    },
)
response.raise_for_status()
data = response.json()
Request
<?php

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.bubbl.tech/platform/v1/notifications/{notification}/archive', [
    'headers' => [
        'Authorization' => 'Bearer bubbl_YOUR_TOKEN',
        'Accept' => 'application/json',
    ],
]);

$data = json_decode((string) $response->getBody(), true);

Unarchive a library notification#

DELETE/notifications/{notification}/archive
Needs notifications:write

Path parameters

notification
string (uuid)
required

The notification ID

Headers

Idempotency-Key
string

A unique value (e.g. a UUID) for this change. A retry with the same key within 24 hours gets the first response back, with Idempotent-Replayed: true, instead of making the change again.

Responses

200
200 response
{
  "data": {
    "id": "0192f0a4-6b1e-7c3a-9d2f-5e8b1a4d5001",
    "name": "Morning flat white offer",
    "type": "message",
    "headline": "Coffee's on us",
    "body": "Show this at the counter for a free flat white before 11am.",
    "media": null,
    "cta_label": "Get the voucher",
    "cta_url": "https://example.com/offers/flat-white",
    "questions": [],
    "created_at": "2026-09-20T09:12:00+00:00",
    "updated_at": "2026-09-20T09:12:00+00:00",
    "archived_at": null
  }
}
Response fields
data
object
required
data.id
string
required
data.name
string
required
data.type
string
required
data.headline
string
required
data.body
string
required
data.media
object | null
required
data.media.id
string
required
data.media.url
string | null
required
data.media.type
string
required
data.cta_label
string | null
required
data.cta_url
string | null
required
data.questions
NotificationQuestionResource[]
required
data.questions[].id
string
required
data.questions[].question_text
string
required
data.questions[].type
string
required
data.questions[].required
boolean
required
data.questions[].choices
string[]
data.archived_at
string | null
required

Archived: it keeps running where it is placed but can't be placed again until unarchived.

data.created_at
string | null
required
data.updated_at
string | null
required
401

The token is missing, unknown, revoked or expired.

missing_tokeninvalid_tokentoken_revokedtoken_expired
  • missing_token

    Missing bearer token.

  • invalid_token

    Unknown API token. Check it was copied in full, and that it is for this environment.

  • token_revoked

    The token "Zapier" was revoked on 2026-10-06 at 18:27 UTC. Issue a new one from Configuration › Platform API.

  • token_expired

    This token has expired. Issue a new one from Configuration › Platform API.

401 response
{
  "error": {
    "code": "missing_token",
    "message": "Missing bearer token."
  }
}
403

The token or workspace can't do this.

missing_abilityplatform_api_not_enabledwrong_environmentworkspace_pausedsandbox_unavailable
  • missing_ability

    This token doesn't have the campaigns:write scope.

  • platform_api_not_enabled

    The full Platform API isn't enabled for this workspace yet. Contact customer services to turn it on.

  • wrong_environment

    This is a Sandbox token: use the Sandbox API address. https://api.sandbox.bubbl.tech/platform/v1

  • workspace_paused

    This workspace is scheduled for deletion; its API access is paused.

  • sandbox_unavailable

    The Sandbox isn't available for this workspace.

403 response
{
  "error": {
    "code": "missing_ability",
    "message": "This token doesn't have the campaigns:write scope."
  }
}
404

Nothing with that ID in this workspace.

not_found
  • not_found

    No such resource in this workspace.

404 response
{
  "error": {
    "code": "not_found",
    "message": "No such resource in this workspace."
  }
}
409

A request with the same Idempotency-Key is still running (retry after Retry-After seconds), or the change conflicts with something that depends on it.

request_in_progress
  • request_in_progress

    This request is still being handled. Try again shortly.

409 response
{
  "error": {
    "code": "request_in_progress",
    "message": "This request is still being handled. Try again shortly."
  }
}
429

Too many requests. Wait for the number of seconds in Retry-After.

rate_limitedtoo_many_failed_attempts
  • rate_limited

    Too many requests. Slow down and try again shortly.

  • too_many_failed_attempts

    Too many failed attempts. Try again shortly.

429 response
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Slow down and try again shortly."
  }
}
Request
curl -X DELETE 'https://api.bubbl.tech/platform/v1/notifications/{notification}/archive' \
  -H 'Authorization: Bearer bubbl_YOUR_TOKEN' \
  -H 'Accept: application/json'
Request
const response = await fetch('https://api.bubbl.tech/platform/v1/notifications/{notification}/archive', {
  method: 'DELETE',
  headers: {
    Authorization: 'Bearer bubbl_YOUR_TOKEN',
    Accept: 'application/json',
  },
});

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

response = requests.request(
    'DELETE',
    'https://api.bubbl.tech/platform/v1/notifications/{notification}/archive',
    headers={
        'Authorization': 'Bearer bubbl_YOUR_TOKEN',
        'Accept': 'application/json',
    },
)
response.raise_for_status()
data = response.json()
Request
<?php

$client = new \GuzzleHttp\Client();

$response = $client->request('DELETE', 'https://api.bubbl.tech/platform/v1/notifications/{notification}/archive', [
    'headers' => [
        'Authorization' => 'Bearer bubbl_YOUR_TOKEN',
        'Accept' => 'application/json',
    ],
]);

$data = json_decode((string) $response->getBody(), true);