{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"c318cee6-1c7c-4307-a1c4-57f30ebf71cf","name":"Crossbeam Partner API","description":"# Authentication\n\nThe Crossbeam API negotiates authentication using [OAuth 2.0](https://oauth.net/2/). If you are looking to integrate the Crossbeam API with an existing application or service, follow the standards for that architecture or ecosystem for OAuth 2.0 authorization using these URLs:\n\n- **Authorization URL**: `https://auth.crossbeam.com/authorize?audience=https://api.getcrossbeam.com`\n    \n- **Access Token URL**: `https://auth.crossbeam.com/oauth/token`\n    \n\nBefore you begin, you will need to create Application in Crossbeam; see the `Custom` section of [https://app.crossbeam.com/integrations](https://app.crossbeam.com/integrations) or see our help docs, found [here](https://help.crossbeam.com/en/articles/4677142-rest-api).\n\nIf you want to get started quickly to kick the tires, see our section on Getting Started with Postman below.\n\n## Scope\n\nOAuth scopes define the permissions your application will request from Crossbeam. For example, you might want to be able to access data about your partnerships, read report data, or be able to read and update threads.\n\nOur documentation for each endpoint includes which scope(s) is required in order to use the endpoint. Here is some base information about choosing a scope value:\n\n- At a minimum, `openid`\n    \n- The scopes for the endpoints you'd like this token to have access to. For example, if you only want to access `/v1/partners`, the scope would be `openid read:partnerships`\n    \n\nFor reference, here is a full list of scopes that our API accepts:\n\n- `openid`\n    \n- `read:partnerships`\n    \n- `read:reports`\n    \n- `read:populations`\n    \n- `write:activity-timeline`\n    \n\n### Access Token Expiry and Refresh Tokens\n\nAccess tokens are only valid for 24 hours. In order to stay authenticated, you may request a Refresh Token.\n\nTo do so, add `offline_access` to your list of scopes when authenticating. For example, if you only want to access `/v1/partners`, the scope would be `openid read:partnerships offline_access`. Y\n\nIn order to exchange a `refresh_token` for a new `access_token`, below is a sample cURL. See the `1. Create an Application` section below to understand how to obtain a client_id and client_secret.\n\n```\ncurl --request POST \\\n  --url 'https://auth.crossbeam.com/oauth/token' \\\n  --header 'content-type: application/x-www-form-urlencoded' \\\n  --data grant_type=refresh_token \\\n  --data 'client_id=YOUR_CLIENT_ID' \\\n  --data client_secret=YOUR_CLIENT_SECRET \\\n  --data refresh_token=YOUR_REFRESH_TOKEN\n\n ```\n\n## Required Headers\n\nMost of our endpoints require 2 headers in order to be authorized. The first is the `Authorization` header containing the OAuth token. For example\n\n`Authorization: Bearer eyJhb...`.\n\nThe second header is used to tell our backend which organization you want to access data for. A Crossbeam user can belong to 1 or more organizations. You can obtain a list of organizations the user belongs to via the `/v0.1/users/me` endpoint. You can then extract the `uuid` field for the organization whose data you wish to access and provide this in the `Xbeam-Organization` header. For example:\n\n`Xbeam-Organization: 02fde942-c7cd-4f12-9d4e-07ee8a57c8c6`\n\n# Sample Client App\n\nWe have an example of how a 3rd party application might interact with the REST API to retrieve tokens. Please note that this source code is provided as-is and is not intended for production use.\n\n- [https://gitlab.com/crossbeam-public/crossbeam-simple-oauth2](https://gitlab.com/crossbeam-public/crossbeam-simple-oauth2)\n    \n\n# Getting Started with Postman\n\nFor quick access to see your data, you can use Postman with this collection. Note that you must use the desktop application, not the web application, which you can download [here](https://www.postman.com/downloads/).\n\n## Demo\n\nIf you'd prefer to watch this tutorial, a demo is available [here](https://www.loom.com/share/635300d9c5b042999b686338b8789b35). Otherwise continue reading.\n\n## 1\\. Create an Application\n\nLog in to Crossbeam and visit [https://app.crossbeam.com/integrations](https://app.crossbeam.com/integrations), where you will see a section to create a custom integration. Click `Create Integration`:\n\n<img src=\"https://content.pstmn.io/dfabaa79-4624-4b2a-bffb-1e204fbc8262/U2NyZWVuIFNob3QgMjAyMi0xMS0wMiBhdCAyLjE3LjQ5IFBNLnBuZw==\">\n\n- **Integration name**: Choose whatever name you'd like to identify this app\n    \n- **Integration description**: Optionally write a description for your app\n    \n- **Callback URL**: Set this to `https://oauth.pstmn.io/v1/callback`\n    \n- **Allowed Origins**: Leave this value blank\n    \n\n<img src=\"https://content.pstmn.io/d2a3aff7-2c1d-4465-8a79-9f2ea5ade191/U2NyZWVuIFNob3QgMjAyMi0xMS0wMiBhdCAyLjE5LjI3IFBNLnBuZw==\">\n\nClick `Create` and once the app has been created, click `View`. Copy the values for `Client ID` and `Client Secret`, you'll need these in the next section.\n\n## 2\\. Configure Postman\n\nAt the top of these docs, click `Run in Postman`:\n\n<img src=\"https://s3.amazonaws.com/assets.getcrossbeam.com/postman/img/run-in-postman.png\">\n\nThis will clone our Postman resources into your Postman app.\n\nNext, select the `Crossbeam` environment as your active environment:\n\n<img src=\"https://s3.amazonaws.com/assets.getcrossbeam.com/postman/img/select-environment.png\">\n\nFinally, we'll edit the `Crossbeam API` collection to enter your Client ID and Secret which you got from the previous step. The `Edit` functionality can be found as shown:\n\n<img src=\"https://s3.amazonaws.com/assets.getcrossbeam.com/postman/img/edit-collection.png\">\n\nClick on the `Variables` tab, where you will see variables for `client_id` and `client_secret`. Set the `Current Value` for these variables to the values you copied from the previous section and then click `Update`.\n\n**Note**: There are other variables in this section which we are not using right now, but will be useful later. In particular, the `scope` variable will control what resources your tokens have access to.\n\n# Rate Limits\n\nRate limits are defined in our security policy and are subject to change with our own discretion.\n\n# Crossbeam Webhooks\n\nA webhook is one way to subscribe to events and receive information in near real time. The Crossbeam Webhook sends **signal** information to the endpoint you provide. For more information on signals, see the **Understanding Signals** section in `/v1/signals/\\\\*`. Webhooks are an enterprise only feature.\n\nFor a detailed walk-through of the installation process through the Crossbeam UI, check out [the documentation in the Crossbeam Help Center](https://help.crossbeam.com/en/articles/12732223-getting-started-with-crossbeam-enriched-apis-and-webhooks).\n\n## Security\n\nThe endpoint on the receiving end of a webhook is typically public. This means there are some extra steps to ensure the messages are actually coming from Crossbeam.\n\n1. Validate the HMAC Signature. When setting up your webhook in the Crossbeam UI, Crossbeam will provide you with a secret key. Every request from Crossbeam will include the header `X-Crossbeam-Signature-256`. This is a base64 encoded string you can use to verify the contents of the message. Using your secret key, hash the contents of the body with the timestamp in `X-Crossbeam-Timestamp` appended and compare that value to the value in `X-Crossbeam-Signature-256`. See the example code for a more precise understanding.\n    \n2. Validate the `X-Crossbeam-Timestamp` header is \"recent\". In this case, the standard for \"recent\" is \"within the past 300 seconds\"\n    \n3. Use an endpoint that is random and difficult to guess\n    \n\n## Retries\n\nCrossbeam will retry the request several times for certain status codes (`408`, `429`, `500`, `502`, `503`, and `504`). After that, a missed message can be retrieved via the rest API.\n\n## What to respond with\n\nPlease respond with a successful status code: likely either 200 or 201. There is no need to respond with anything in the body.\n\n## Example Code\n\nThis is a minimal Flask app that receives a request and verifies it in the way Crossbeam expects you to.\n\n``` python\nfrom flask import Flask, request, abort\nimport hmac\nimport hashlib\nimport time\nimport base64\napp = Flask(__name__)\n# Shared secret key (received in the Crossbeam UI)\nWEBHOOK_SECRET = b\"111122223333secret\"\n# Allowed timestamp drift (in seconds)\nMAX_TIMESTAMP_AGE = 300  # 5 minutes\ndef verify_signature_and_timestamp(request):\n    \"\"\"Verify the request signature and timestamp header.\"\"\"\n    received_signature = request.headers.get(\"X-Crossbeam-Signature-256\")\n    received_timestamp = request.headers.get(\"X-Crossbeam-Timestamp\")\n    if not received_signature or not received_timestamp:\n        return False, \"Missing required headers\"\n    try:\n        received_timestamp = int(received_timestamp)\n    except ValueError:\n        return False, \"Invalid timestamp format\"\n    now = int(time.time())\n    if abs(now - received_timestamp) > MAX_TIMESTAMP_AGE:\n        return False, \"Timestamp too old or too new\"\n    # Build the signed payload string: \"body+timestamp\"\n    signed_data = f\"{request.data.decode()}{received_timestamp}\".encode()\n    computed_hmac = hmac.new(WEBHOOK_SECRET, signed_data, hashlib.sha256).digest()\n    # Crossbeam's signature is base64 encoded\n    computed_signature = base64.b64encode(computed_hmac).decode()\n    if not hmac.compare_digest(received_signature, computed_signature):\n        return False, \"Invalid signature\"\n    return True, \"Valid\"\n@app.route(\"/webhook/61e68950-415c-4618-84a2-7bffdc6588ad\", methods=[\"POST\"])\ndef webhook():\n    # Validate the request\n    is_valid, message = verify_signature_and_timestamp(request)\n    if not is_valid:\n        print(message)\n        abort(403)\n    payload = request.get_json()\n    # now you can trust the payload is from Crossbeam and process it!\n    # for now, we just print it\n    print(payload)\n    return {}, 200\nif __name__ == \"__main__\":\n    app.run(host=\"0.0.0.0\", port=5000, debug=True)\n\n ```","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"13379768","team":176493,"collectionId":"c318cee6-1c7c-4307-a1c4-57f30ebf71cf","publishedId":"2s8Z6savX9","public":true,"publicUrl":"https://developers.crossbeam.com","privateUrl":"https://go.postman.co/documentation/13379768-c318cee6-1c7c-4307-a1c4-57f30ebf71cf","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"documentationLayout":"classic-double-column","customisation":{"metaTags":[{"name":"description","value":""},{"name":"title","value":""}],"appearance":{"default":"light","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.0","publishDate":"2025-06-20T14:22:29.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{"title":"","description":""},"logos":{"logoLight":null,"logoDark":null}},"statusCode":200},"environments":[{"name":"Crossbeam","id":"20426efd-f6df-4e71-aa5d-3663a8438ac0","owner":"22933419","values":[{"key":"base_api_url","value":"https://api.crossbeam.com","enabled":true},{"key":"base_auth_url","value":"https://auth.crossbeam.com","enabled":true},{"key":"audience","value":"https://api.getcrossbeam.com","enabled":true},{"key":"auth_url","value":"{{base_auth_url}}/authorize?audience={{audience}}","enabled":true},{"key":"access_token_url","value":"{{base_auth_url}}/oauth/token","enabled":true},{"key":"scope","value":"openid read:populations read:threads read:partners read:partnerships read:reports offline_access","enabled":true},{"key":"client_id","value":"","enabled":true},{"key":"client_secret","value":"","enabled":true},{"key":"xbeam_organization","value":"","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/c727eb4b7dc6d60255f8b52482fbf80d6a3a4978d9a2511b7394d7f253c84955","favicon":"https://res.cloudinary.com/postman/image/upload/v1605818251/team/uhndkgtyem9ilggfkvrs.ico"},"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":"Crossbeam","value":"22933419-20426efd-f6df-4e71-aa5d-3663a8438ac0"}],"canonicalUrl":"https://developers.crossbeam.com/view/metadata/2s8Z6savX9"}