{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"9371bc4a-1be3-4ab9-8728-040521255f3b","name":"MagicBell REST API (v1)","description":"## The Basics\n\n|  |  |\n| --- | --- |\n| Endpoint | `https://api.magicbell.com` |\n| `Accept` | `application/json` |\n| `Content-Type` | `application/json` |\n\n## Authentication\n\nThe MagicBell REST API utilizes an HTTP header based authentication using your MagicBell's project's API key and secret. Your MagicBell project's API key and secret are available in the \"Settings\" section of your MagicBell Admin Dashboard.\n\nWhile the API key of your project can be distributed freely, **do not publish the API secret**.\n\n### Admin operations\n\nAll API requests that perform an admin operation (like fetch all users or create notifications) require:\n\n- the `X-MAGICBELL-API-KEY` header containing your MagicBell project's API key\n    \n- the `X-MAGICBELL-API-SECRET` header containing your MagicBell project's API secret\n    \n\n``` curl\ncurl https://api.magicbell.com/broadcasts \\\n  --request POST \\\n  --header 'X-MAGICBELL-API-KEY: [MAGICBELL_API_KEY]' \\\n  --header 'X-MAGICBELL-API-SECRET: [MAGICBELL_API_SECRET]' \\\n  --data '{\n    \"broadcast\": {\n      \"title\": \"Ticket assigned to you: Do you offer demos?\",\n      \"recipients\": [{\n        \"email\": \"richard@example.com\"\n      }]\n    }\n  }'\n\n ```\n\n``` javascript\nfetch('https://api.magicbell.com/broadcasts', {\n  method: 'POST',\n  headers: {\n    'X-MAGICBELL-API-KEY', '[MAGICBELL_API_KEY]',\n    'X-MAGICBELL-API-SECRET', '[MAGICBELL_API_SECRET]',\n  },\n  body: JSON.stringify({\n    broadcast: {\n      title: \"Ticket assigned to you: Do you offer demos?\",\n      recipients: [{\n        email: \"richard@example.com\"\n      }]\n    }\n  })\n});\n\n ```\n\n### Other operations\n\nYour users can perform some operations over their notifications (like fetch and delete them). All API requests to endpoints that perform these operations require:\n\n- the `X-MAGICBELL-API-KEY` header containing your MagicBell project's API key\n    \n- the `X-MAGICBELL-USER-EXTERNAL-ID` header containing the ID of the user performing the request\n    \n- the `X-MAGICBELL-USER-HMAC` header containing the computed hash for the user ID\n    \n\n``` curl\ncurl https://api.magicbell.com/notifications \\\n  --request GET \\\n  --header 'X-MAGICBELL-API-KEY: [MAGICBELL_API_KEY]' \\\n  --header 'X-MAGICBELL-USER-EXTERNAL-ID: [USER_ID]'\n  --header 'X-MAGICBELL-USER-HMAC: [USER_ID_HMAC]'\n\n ```\n\n``` javascript\nfetch('https://api.magicbell.com/notifications', {\n  headers: {\n    'X-MAGICBELL-API-KEY', '[MAGICBELL_API_KEY]',\n    'X-MAGICBELL-USER-EXTERNAL-ID', '[USER_ID]',\n    'X-MAGICBELL-USER-HMAC', '[USER_ID_HMAC]',\n  },\n});\n\n ```\n\nOn the other hand, if you identify users in your app by email, set the `X-MAGICBELL-USER-EMAIL` header instead:\n\n``` curl\ncurl https://api.magicbell.com/notifications \\\n  --request GET \\\n  --header 'X-MAGICBELL-API-KEY: [MAGICBELL_API_KEY]' \\\n  --header 'X-MAGICBELL-USER-EMAIL: [USER_EMAIL]'\n  --header 'X-MAGICBELL-USER-HMAC: [USER_EMAIL_HMAC]'\n\n ```\n\n``` javascript\nfetch('https://api.magicbell.com/notifications', {\n  headers: {\n    'X-MAGICBELL-API-KEY', '[MAGICBELL_API_KEY]',\n    'X-MAGICBELL-USER-EMAIL', '[USER_EMAIL]',\n    'X-MAGICBELL-USER-HMAC', '[USER_EMAIL_HMAC]',\n  },\n});\n\n ```\n\nNotice that in this scenario, you should use your API secret to compute an HMAC of the user's email, instead of the user's id.\n\nIf you set both the email and the external ID in the HTTP headers when performing a request the external ID will take precedence over the email.\n\nIf you're yet to turn to HMAC authentication for your MagicBell project, you don't have to provide the `X-MAGICBELL-USER-HMAC` header. However, we highly recommend [turning on HMAC authentication](https:///docs/hmac-authentication) before releasing MagicBell to your users. This will help preventing users from fetching data from other users of your app.\n\n## API Spec\n\nThe MagicBell REST API is described in an OpenAPI 3.0 document. To use it with a REST client or to create custom wrappers, [download the OpenAPI Spec.](https://public.magicbell.com/specs/openapi.v1.json)\n\n## Client errors\n\nThe MagicBell REST API utilizes [HTTP response codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) to indicate the success or failure of an API request. A `2xx` response code indicates success, and a `4xx` response code means that the API request is incorrect (like when a required parameter is missing or a resource, like a user, could not be found). A `5xx` response code indicates an error in MagicBell's servers. These are rare, and we always act quickly to solve them.\n\nWhen the API responds with a `4xx` response code, the response body includes an array that contains all the errors that have happened. For example:\n\n``` json\n{\n  \"errors\": [\n    {\n      \"code\": \"api_secret_not_provided\",\n      \"message\": \"API Secret not provided\"\n    }\n  ]\n}\n\n ```\n\nAs shown above, some errors also have a `code` that briefly describes the error that has happened. These are the possible error codes:\n\n- `api_key_not_provided`\n    \n- `incorrect_api_key`\n    \n- `api_secret_not_provided`\n    \n- `api_secret_is_incorrect`\n    \n- `forbidden`\n    \n- `neither_user_hmac_nor_api_secret_provided`\n    \n- `user_email_not_provided`\n    \n\nYou can handle these errors and take necessary action, like displaying an appropriate error message to the users or reporting the event to your error tracker. For example:\n\n``` js\nconst axios = require('axios');\nconst headers = {\n  'X-MAGICBELL-API-SECRET': 'MAGICBELL_API_SECRET',\n  'X-MAGICBELL-API-KEY': 'MAGICBELL_API_KEY',\n};\nconst data = {\n  broadcast: {\n    title: \"We're processing your order\",\n  },\n};\naxios.post('https://api.magicbell.com/broadcasts', data, headers).catch((error) => {\n  const { response } = error;\n  ErrorTracker.notify(response.data, response.status);\n});\n\n ```\n\n## Rate limits\n\nThe REST API imposes a limit of 100 requests/minute for most `GET/OPTIONS/HEAD` endpoints and 60 requests/minute for `POST/PATCH/PUT/DELETE` endpoints.\n\nYou will get an HTTP 429 Too Many Requests response if you send requests fasters than that, often accompanied by a helpful error message explaining the limit you have hit. Unless you are on an Enterprise plan, these limits are subject to change without announcement.\n\nPlease note that many of our endpoints support batching or bulk actions, which can reduce the number of requests you make. For example, `POST /notifications` supports multiple recipients in a single request.\n\nMany of our API endpoints support bulk operations, and we recommend using them to reduce the number of requests you make.\n\n## Idempotent requests\n\nThe API supports idempotent requests to prevent the same operation from being performed twice for some endpoints. If you attempt an operation twice or more, we will process only the first attempt. For example, suppose a request to create a notification does not respond due to a network connection error. In that case, you can retry the request with the same idempotency key and it will create no additional notification.\n\nTo perform an idempotent request, you need to add an `Idempotency-Key:` header on the request. An idempotency key is a unique value generated on your side, which the server uses to recognize subsequent retries of the same request. We suggest using UUID to avoid collisions.\n\nThe resulting status code and body of the first request will be cached. Subsequent requests with the same idempotency key will return the same result. The cached results will expire after 24 hours.\n\n``` curl\ncurl https://api.magicbell.com/broadcasts \\\n  --request POST \\\n  --header 'X-MAGICBELL-API-KEY: MAGICBELL_API_KEY' \\\n  --header 'X-MAGICBELL-API-SECRET: MAGICBELL_API_SECRET' \\\n  --header 'IDEMPOTENCY-KEY: YOUR_IDEMPOTENCY_KEY' \\\n  --data '{\n    \"broadcast\": {\n        \"title\": \"Task assigned to you: Upgrade to Startup plan\",\n        \"content\": \"Hello, can you upgrade us to the Startup plan. Thank you.\",\n        \"category\": \"billing\",\n        \"action_url\": \"https://magicbell.com/pricing\",\n        \"recipients\": [\n          { \"email\": \"mary@example.com\" },\n          { \"email\": \"richard@example.com\" }\n        ]\n    }\n  }'\n\n ```\n\n``` ruby\nrequire 'httparty'\nheaders = {\n  \"X-MAGICBELL-API-KEY\": \"MAGICBELL_API_KEY\",\n  \"X-MAGICBELL-API-SECRET\": \"MAGICBELL_API_SECRET\",\n  \"IDEMPOTENCY-KEY\": \"YOUR_IDEMPOTENCY_KEY\",\n}\nbody = {\n  notification: {\n    title: \"Task assigned to you: Upgrade to Startup plan\",\n    content: \"Hello, can you upgrade us to the Startup plan. Thank you.\",\n    category: \"billing\",\n    action_url: \"https://magicbell.com/pricing\",\n    recipients: [\n      { email: \"mary@example.com\" },\n      { email: \"richard@example.com\" }\n    ]\n  }\n}\nresponse = HTTParty.post(\"https://api.magicbell.com\", { body: body.to_json, headers: headers })\n\n ```\n\n``` python\nimport requests\nheaders = {\n    'X-MAGICBELL-API-KEY': 'MAGICBELL_API_KEY',\n    'X-MAGICBELL-API-SECRET': 'MAGICBELL_API_SECRET',\n    'IDEMPOTENCY-KEY': 'YOUR_IDEMPOTENCY_KEY',\n}\ndata = {\n    \"broadcast\": {\n        \"title\": \"Task assigned to you: Upgrade to Startup plan\",\n        \"content\": \"Hello, can you upgrade us to the Startup plan. Thank you.\",\n        \"category\": \"billing\",\n        \"action_url\": \"https://magicbell.com/pricing\",\n        \"recipients\": [\n            { \"email\": \"mary@example.com\"},\n            { \"email\": \"richard@example.com\"}\n        ]\n    }\n}\nresponse = requests.post('https://api.magicbell.com/broadcasts', headers=headers, json=data)\n\n ```\n\n``` javascript\nimport axios from 'axios';\nconst headers = {\n  'X-MAGICBELL-API-KEY': 'MAGICBELL_API_KEY',\n  'X-MAGICBELL-API-SECRET': 'MAGICBELL_API_SECRET',\n  'IDEMPOTENCY-KEY': 'YOUR_IDEMPOTENCY_KEY',\n};\nconst data = {\n  broadcast: {\n    title: 'Task assigned to you: Upgrade to Startup plan',\n    content: 'Hello, can you upgrade us to the Startup plan. Thank you.',\n    category: 'billing',\n    action_url: 'https://magicbell.com/pricing',\n    recipients: [{ email: 'mary@example.com' }, { email: 'richard@example.com' }],\n  },\n};\naxios.post('https://api.magicbell.com/broadcasts', data, { headers });\n\n ```","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"2269098","team":2567598,"collectionId":"9371bc4a-1be3-4ab9-8728-040521255f3b","publishedId":"2sAYdhLAjv","public":true,"publicUrl":"https://documenter-api.postman.tech/view/2269098/2sAYdhLAjv","privateUrl":"https://go.postman.co/documentation/2269098-9371bc4a-1be3-4ab9-8728-040521255f3b","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"documentationLayout":"classic-double-column","customisation":{"metaTags":[{"name":"description","value":"MagicBell's REST API (v1) reference."},{"name":"title","value":""}],"appearance":{"default":"dark","themes":[{"name":"dark","logo":null,"colors":{"top-bar":"212121","right-sidebar":"303030","highlight":"FF6C37"}},{"name":"light","logo":null,"colors":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"}}]}},"version":"8.10.1","publishDate":"2025-03-01T12:25:55.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{"title":"","description":"MagicBell's REST API (v1) reference."},"logos":{"logoLight":null,"logoDark":null}},"statusCode":200},"environments":[{"name":"Production","id":"0932d1c1-5f6d-403f-9729-2bd025525da3","owner":"17705142","values":[{"key":"baseUrl","value":"https://api.magicbell.com","enabled":true}],"published":true}],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/f6165f26de3b0b073b25df6c2c3f7fc1c5b33ef7e4e5e93415c355f7aab63065","favicon":""},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"},{"label":"Production","value":"17705142-0932d1c1-5f6d-403f-9729-2bd025525da3"}],"canonicalUrl":"https://documenter.gw.postman.com/view/metadata/2sAYdhLAjv"}