On this page and tools
Checked against the live API on October 10, 2026.
Report an error on this pageStart here
Authentication
Every request to the Bynefit App is authenticated with a bearer token. Pick the kind that matches what you are doing, and start with its test version while you build. For end-user sign-in (third-party apps using Bynefit accounts to log users in), see OAuth 2.0 / OpenID Connect instead.
Types of keys
| Key type | Get it at | Good for |
|---|---|---|
Developer keybapi_pk_… |
/dash/developers/keys | Reading public data, submitting resources for review. No team required. |
Team keybapi_tk_… |
/dash/integrations/api-tokens | Managing your organization's own directory, receiving webhooks for your team, running embed widgets. |
Agent keybapi_ag_… |
/dash/integrations/agent-keys | An AI agent reading your Space: read-only to start, short-lived, test mode first. Send it only as a bearer header. See Agent keys. |
Test keysbapi_pk_test_…bapi_tk_test_… |
The same pages. Choose Test in Create key. | Building and trying things. Same addresses and answers, sample data only, ready with no review. See Test mode. |
Sending the key
Put the key in the Authorization header using the Bearer scheme:
GET /dash/api/v1/resources HTTP/1.1 Host: bynefit.comAuthorization: Bearer bapi_pk_1a2b3c…
That is it: no signing, no query string, no separate refresh tokens. Every answer to a key says which mode it ran in, with the header X-Bynefit-Mode set to live or test.
What each key can do
Every key has a list of scopes that describe what it can access. Developer keys are limited to public scopes (read public data and submit proposals). Team keys can hold additional scopes that their organization has enabled, such as directory management. A test key can hold any of them straight away, because it only ever touches sample data.
| Permission | What it allows | Access |
|---|---|---|
read:events | Activity. See what happened in your Space, like a task created or a form submitted. Newest first. | Open |
read:tasks | Tasks. Look up a single task by its id. | Open |
read:users | Member profiles. Look up a member's public profile. No email address. | Open |
read:forms | Forms and answers. Read your forms and what people sent in. Answers can include personal details. The respondent email field is left out unless the key also has Member emails, but an email a person typed into an answer is still included. | Open |
read:payments | Payments. Read the payment records for your Space. | Open |
read:* | Everything readable. Every read permission above, including ones added later. Member emails are never included. | Open |
read:users:pii | Member emails. Adds each member's email address to profile lookups, and the respondent email address to form submissions. | Sensitive, by approval |
embed:widget | Website widget. Lets the Bynefit widget load on your own website. List that website under allowed websites. | Open |
write:resources | Manage your directory. Add, change or delete your directory entries from a spreadsheet or another system. | By approval |
write:beacons | Send product events. Send the events your app or site reports, in batches, so Bynefit can show you how people use it. | Partner Spaces |
read:beacons | Read event totals. Read the counts of the events you have sent, by event and by day. | Partner Spaces |
read:resources:public | Read the public directory. List the approved community resources, newest first. No Space information. | Open |
write:resources:public | Suggest directory entries. Send new entries for Bynefit staff to review. Nothing is published until it is approved. | Open |
read:site-files | Read your site files. List your hosted sites, read their files and see the saved versions of a file. | Partner Spaces |
write:site-files | Change your site files. Create, replace and delete files on your hosted site. Every change is versioned, scanned for secrets and logged, and deleted files go to the trash. | Partner Spaces |
write:forms | Create and manage your forms. Create forms, change their settings, add, change, reorder and delete their fields, and pause or delete a form that has no submissions. Registration forms stay with the owner, and no submission is read or changed. | Partner Spaces |
read:engagement-types | Read your engagement types. List and read the engagement types of your Space: their stages, the form and booking type they link to, and their default items. No engagement or client is read. | Partner Spaces |
write:engagement-types | Create and manage your engagement types. Create engagement types, change their stages, linked form, booking type and default items, switch them off, and delete a type no engagement uses. No engagement or client is read or changed. | Partner Spaces |
Open permissions are available as soon as the key is made. By approval permissions are switched on for your Space after Bynefit reviews the request. Sensitive, by approval permissions expose personal details such as email addresses and need that review too. Partner Spaces permissions are turned on for partner Spaces only. Keep a key to the fewest permissions it needs: a request for something it does not hold is refused no matter which names you know.
If you call an endpoint your key isn't scoped for, you'll get a 403 back with a short hint telling you which scope is missing, and nothing more.
Errors
| Status | Error | When |
|---|---|---|
401 | missing_or_invalid_token | The key is missing, malformed or unknown. |
401 | token_revoked | The key was revoked. Make a new one. |
401 | token_expired | The key passed its expiry date. Make a new one. |
401 | missing_or_invalid_key | The partner key is missing or not recognised. |
401 | key_in_url | A write endpoint does not take a key in the address. Send it as an Authorization Bearer header and revoke the key that was exposed. |
401 | bad_signature | The request signature did not match. Sign the exact body you send. |
403 | insufficient_scope | The key is valid but not scoped for this endpoint. The response names the missing scope in required. |
403 | domain_not_authorized | The request came from a web address this key is not allowed on. |
403 | origin_not_allowed | The request origin is not allowed for this key. |
403 | not_a_partner | The Space is not enrolled as a partner. |
403 | partner_paused | The partner is paused, so this call is refused until it is resumed. |
404 | not_found | There is nothing with that id, or the key cannot see it. |
404 | not_enabled | This feature is not switched on yet. |
404 | unknown_resource | There is no such resource in v1, or this key type cannot reach it. |
404 | unknown_subresource | There is no such sub-resource under that resource. |
405 | method_not_allowed | That HTTP method is not supported on this endpoint. The Allow header lists the ones that are. |
400 | invalid_json | The request body is not valid JSON. |
400 | events_required | The body needs a non-empty events list. |
400 | invalid_id | The id is not in the expected format for this resource. |
400 | invalid_since | since must be an ISO-8601 date-time. |
400 | invalid_cursor | The cursor is not one this endpoint issued. Start again without it. |
400 | invalid_sort | The sort value is not one this endpoint supports. |
400 | invalid_offset | offset must be a whole number of zero or more. |
400 | invalid_paging | The paging parameters are not valid together. |
400 | invalid_assignee | The assignee is not a member of this Space. |
413 | batch_too_large | The request carries more items than one call accepts. Split it. |
413 | body_too_large | The request body is larger than this endpoint accepts. |
400 | invalid_idempotency_key | Idempotency-Key must be 8 to 255 printable characters with no spaces. |
409 | idempotency_key_reused | That Idempotency-Key was already used with a different request. Use a new key for a new request. |
409 | idempotency_in_progress | The first request with this Idempotency-Key is still running. Retry after Retry-After. |
503 | idempotency_unavailable | Idempotency-Key cannot be honoured right now, so nothing was done. Retry later. |
402 | usage_exhausted | The Space has used all its agent units and has no pack credit, extra usage or automatic top up. Stop and tell the owner; top_up_url in the body is where they add units. |
429 | rate_limited | Too many requests in the trailing hour. Wait for Retry-After. |
429 | resend_too_soon | That invitation was sent recently. Wait for Retry-After. |
500 | server_error | Something failed on our side. Retry, and quote the request_id if it keeps happening. |
403 | test_mode_unsupported | A test key called something that has no sample data. Use a live key there. |
Errors from the authenticated /dash/api/v1 resource endpoints, the partner business and promotion
endpoints and the test-mode sandbox have an error code, a request_id and a
docs_url that links to the explanation. The partner beacon endpoints do not carry them yet.
The same ID is in the X-Request-Id response header. Quote it when you contact
support and we can find your call.
Safe retries with Idempotency-Key
Available The v1 endpoints that create something take an Idempotency-Key header, so a retry after a timeout cannot do the work twice:
POST /dash/api/v1/partner/businesses, POST /dash/api/v1/partner/businesses/{ref}/promotions
and POST /dash/api/v1/agent/access-requests.
- Make up a unique value for each attempt, 8 to 255 printable characters with no spaces. A random UUID is fine.
- Send the same request again with the same key within 24 hours and you get the first answer back, with the same status and body and the header
Idempotent-Replayed: true. Nothing is done a second time. - The same key with a different body, or for a different address, is refused with
409 idempotency_key_reused. Use a new key for a new request. - If the first request is still running, a retry gets
409 idempotency_in_progressandRetry-After. Wait and send it again. - A
5xxor429answer is not kept, so retrying it with the same key runs the request again. - Keys belong to the key that sent them. Another key, another Space or another partner can use the same value and never sees your answer.
- If the key cannot be honoured right now you get
503 idempotency_unavailableand nothing is done.
The business and promotion endpoints already treat your own ref as a safe retry. The header adds the exact first answer, including its status, for retries that cross a rate limit or a timeout.
Limits
Each key has an hourly allowance. Past it you get a 429 until the hour rolls over.
| Key | Allowance |
|---|---|
| Developer key | 60 calls per hour |
| Free Space key | 1,000 calls per hour |
| Paid Space key | 10,000 calls per hour |
On free and paid plans, all of a Space's keys together are held to 3 times one key's allowance, so more keys do not mean more calls.
Plans with usage billing are not capped this way.
Responses carry X-RateLimit-Limit and X-RateLimit-Remaining for the key, X-RateLimit-Team-Limit and X-RateLimit-Team-Remaining for the Space, and X-RateLimit-Reset.
If a key is exposed
- Go back to the page where you created it.
- Click Revoke on the affected row.
- Create a new key and update the integration that used it.
Revoked keys stop working immediately.