Enterprise API Guide
Enterprise API Guide
Enterprise accounts only. An enterprise token can only be created on an enterprise's corporate team, by someone who is an owner or admin of that team and of the enterprise account. Standalone teams and branch teams can't create or use one, and their own tokens (user, team or app tokens) always work on their own team only: they ignore
teamId.
This guide is for enterprises (a corporate team with branch teams under it) that want one integration to work with any branch, without creating an API token per branch.
Overview
An enterprise token is an API token that belongs to your enterprise's corporate team. It can use the Partner API on any branch of the enterprise, one branch per request: every request names its branch with teamId, and behaves exactly as if it had been made with that branch's own Team token, limited to the permissions you gave the token.
Two endpoints span the whole enterprise and don't need a teamId:
- List your branches.
GET /api/partner/teamsreturns every team in the enterprise. - Find a user in any branch.
GET /api/partner/users?emailExact=...searches every branch and tells you which branch(es) the user is on.
Everything else (contacts, events, tasks, notes, loans, contracts, and so on) takes a teamId. The most common use is lead routing: sending a loan application from your LOS to the loan officer named on it:
GET /api/partner/[email protected] → user id + their branch(es)
POST /api/partner/events?teamId=<branch id> → contact created or matched in that branch,
{ person: { assignedUserId: <user id>, ... } } assigned to the loan officerIs an enterprise token right for me? Use one when a single system has to reach several branches. If your integration only ever talks to one branch, a regular Team token on that branch is simpler. See Authentication & API Keys.
Creating an Enterprise Token
Enterprise tokens are only available:
- on a team that belongs to an enterprise and is marked as its corporate team, and
- to a user who is an owner or admin of the corporate team and an owner or admin of the enterprise account.
To create one:
- Log in to Sure Send CRM and switch to your corporate team.
- Go to Settings → API Tokens and click New Token.
- Under Scope, choose Enterprise Scope (All branches). If you don't see it, you're not on the corporate team or you aren't an enterprise owner/admin.
- Choose the token's permissions (see below) and click Create Token.
- Copy the token. It is shown only once.
Permissions
An enterprise token must list its permissions. Give it only what your integration needs: the token reaches every branch, so each permission applies to all of them.
| Permission | Allows (on the branch named by teamId) |
|---|---|
read_team | List the enterprise's teams (GET /api/partner/teams, no teamId needed) |
read_users | Look up users across every branch (GET /api/partner/users, no teamId needed) |
read_people / write_people | View / create, update and delete contacts |
read_events / write_events | View / send events (leads), creating or matching the contact |
read_companies / write_companies | View / manage companies |
read_tasks / write_tasks | View / manage tasks |
read_notes / write_notes | View / manage notes |
read_appointments / write_appointments | View / manage appointments |
read_calls / write_calls | View / log calls |
read_emails / write_emails | View / log or send emails (see Sending email and texts) |
read_sms / write_sms | View / log or send text messages (see Sending email and texts) |
read_stages | View stages and pipelines |
full_access | Everything above, plus every other Partner API endpoint (loans, contracts, custom fields, automations, smart lists, ponds, templates, library, reports, webhooks, …) apart from the blocked ones below |
Endpoints that aren't covered by a specific permission, such as loans, contracts and custom fields, are only available with full_access.
For lead routing, read_team, read_users and write_events are enough. They are pre-selected when you create the token.
What an enterprise token can't do
Whatever permissions it has, including full_access, an enterprise token can't:
- manage users or roles (
POST/PUT/DELETE /api/partner/users); - change team settings (
PUT /api/partner/teams/{id}) or voice settings; - manage API systems (
/api/partner/apiSystems); - use the AI endpoints (
/api/partner/ai/*, which spend AI credits) or inbox apps (/api/partner/inbox_apps/*); - create, accept, decline or close referrals, or sign a referral partner's MSA;
- use webhooks for
emailsCreatedoremailsUpdated(their payloads carry email content from every mailbox on the branch, including unshared ones): it can't subscribe to them, edit a webhook that has them (or has ever delivered them), or read, retry or replay their deliveries. Read shared email withGET /api/partner/emailMessagesinstead; - call anything outside the Partner API.
Those requests return 403 with code enterprise_token_endpoint_not_allowed.
When the token stops working
The token is checked on every request. It stops working (401) if:
- the team it was created on is no longer the enterprise's corporate team, or leaves the enterprise;
- the user who created it is no longer an owner/admin of the corporate team or of the enterprise account;
- the enterprise's subscription lapses. This stops the token on every branch at once (
401with"error": "Unauthorized"), unlike a single branch whose subscription isn't active, which returns402for that branch only; - it expires, or is revoked in Settings → API Tokens.
If the creator leaves, an enterprise owner or admin should create a new token.
Verifying Your Token
curl https://api.suresend.ai/api/partner/identity \
-H "Authorization: Bearer suresendcrm_your_token"{
"account": { "id": "7d1e…", "name": "Example Lending HQ" },
"user": { "id": "a41c…", "email": "[email protected]", "firstName": "Integrations", "lastName": "Admin" },
"tokenScope": "enterprise",
"enterpriseAccount": { "id": "c9f0…", "name": "Example Lending" }
}For an enterprise token, account is the corporate team and user is the person who created the token.
Step 1: List Your Branches (optional)
curl https://api.suresend.ai/api/partner/teams \
-H "Authorization: Bearer suresendcrm_your_token"{
"teams": [
{
"id": "1b2c…",
"name": "Austin Branch",
"isCorporate": false,
"parentTeamId": null,
"subscriptionActive": true,
"memberCount": 14,
"createdAt": "2026-03-02T15:04:05Z",
"updatedAt": "2026-10-30T09:12:44Z"
},
{
"id": "7d1e…",
"name": "Example Lending HQ",
"isCorporate": true,
"parentTeamId": null,
"subscriptionActive": true,
"memberCount": 6,
"createdAt": "2026-01-15T10:00:00Z",
"updatedAt": "2026-10-30T09:12:44Z"
}
]
}| Field | Meaning |
|---|---|
isCorporate | This is the enterprise's corporate team |
parentTeamId | The team's region (parent company), if your enterprise uses regions |
subscriptionActive | false means leads sent to this branch will be refused until its subscription is active |
memberCount | Number of users on the team |
The list changes rarely, so you can cache it (for example for an hour). GET /api/partner/teams/{id} returns one team, and 404 for a team outside your enterprise.
Step 2: Find the User and Their Branch
curl "https://api.suresend.ai/api/partner/[email protected]" \
-H "Authorization: Bearer suresendcrm_your_token"{
"users": [
{
"id": "e5a7…",
"firstName": "Jordan",
"lastName": "Rivera",
"email": "[email protected]",
"teams": [
{ "id": "1b2c…", "name": "Austin Branch", "role": "member", "isCorporate": false }
]
}
],
"hasMore": false,
"nextOffset": null
}(Other user fields, such as phone, emailAccounts and smsNumbers, are omitted here.)
- Without
teamId, the search covers every branch in the enterprise. AddteamId=<branch id>to search one branch. - Each user's
teamslists the enterprise teams they belong to. Use one of these ids asteamIdin Step 3. - Use
emailExact, notemail, for routing.emailis a partial match, so[email protected]also finds[email protected].emailExactmatches one whole address, ignoring case. GET /api/partner/users/{id}returns one user, with the sameteamslist.
Decide the branch from teams:
teams contains | What to do |
|---|---|
| One team | Send the lead to that team |
| Several teams | The user works in more than one branch. Pick the branch with your own rule (for example, the branch on the application) |
| Nothing (user not found) | The user isn't in your enterprise. Don't send the lead; fix the email or the user's setup in Sure Send |
Step 3: Send the Lead to the Branch
Pass the branch as teamId, either in the query string, in the JSON body, or as an X-Team-Id header, and set person.assignedUserId to the user's id:
curl -X POST "https://api.suresend.ai/api/partner/events?teamId=1b2c…" \
-H "Authorization: Bearer suresendcrm_your_token" \
-H "Content-Type: application/json" \
-d '{
"source": "Lodasoft",
"type": "registration",
"message": "New loan application",
"person": {
"firstName": "Avery",
"lastName": "Borrower",
"assignedUserId": "e5a7…",
"emails": [{ "value": "[email protected]", "isPrimary": true }],
"phones": [{ "value": "+15125550123", "isPrimary": true }]
}
}'The response is the same as for any POST /api/partner/events call: 201 when a new contact was created, 200 when an existing contact in that branch was matched. See the Events API Guide for every field you can send.
POST /api/partner/people works the same way (with teamId and a top-level assignedUserId) if your token has write_people. Prefer /events, though: it matches an existing contact instead of returning 409, and it records the lead as an event on the contact's timeline.
Sending email and texts
An enterprise token works on a branch as that branch's owner, so it must say who it is sending as. It never falls back to the owner's own address or number:
- Email (
POST /api/partner/emailMessageswithsend: true):fromEmailis required, and the message must go through a team-wide email provider whose sending domain matchesfromEmail. A user's personal mailbox (for example a connected Gmail) can't be used. - Text (
POST /api/partner/textMessageswithsend: true):fromNumberis required (any number on the branch's SMS provider), or send through a Sendblue line withsendblueLineId.
Recording a message that was sent elsewhere (without send: true) needs neither.
How duplicates are matched
Duplicate matching happens within the branch you send to. The contact is matched by email, then phone, among that branch's contacts only:
- Sending the same borrower twice to the same branch matches the existing contact (
200). That contact keeps its current assignee; a newassignedUserIddoes not reassign it. - Sending the same borrower to two different branches creates a contact in each.
Errors
Enterprise-specific errors use the usual Partner API error shape, plus a machine-readable code:
{ "errorMessage": "teamId is required for enterprise API tokens. …", "code": "enterprise_team_required" }| Status | code | Meaning | What to do |
|---|---|---|---|
400 | enterprise_team_required | A request other than the teams, users and identity lookups was sent without teamId | Add teamId. Nothing is ever read from or written to a branch you didn't name |
404 | enterprise_team_not_found | teamId isn't a team in your enterprise | Use an id from GET /api/partner/teams or from the user's teams |
422 | assignee_not_on_team | assignedUserId isn't a member of the teamId branch | Look the user up again and send to one of their teams |
422 | enterprise_team_has_no_owner | The branch has no owner or admin to record the contact under | Ask the enterprise to add an owner or admin to the branch |
403 | enterprise_token_endpoint_not_allowed | That endpoint isn't available to enterprise tokens | See What an enterprise token can't do |
403 | enterprise_token_mailbox_events_not_allowed | A webhook create or update involved emailsCreated / emailsUpdated | See What an enterprise token can't do |
403 | insufficient_scope | The token lacks the permission for that endpoint (endpoints without a specific permission need full_access) | Create a token with the needed permission |
422 | Sending email or a text without fromEmail / fromNumber, or through a personal mailbox | See Sending email and texts | |
401 | The token is invalid, expired or revoked, or has stopped working | See When the token stops working | |
402 | subscription_inactive | The branch's subscription isn't active (subscriptionActive: false). The body also carries error and message for older clients | Hold the lead and retry once the branch is active |
Retry 429 and 503 responses after the Retry-After header, as with any Partner API call.
Rate Limits and Reliability
- Rate limit. Enterprise tokens get 600 requests per minute, the same as a registered System ID (sending one as well doesn't raise it further). All of your enterprise tokens share that allowance, per resource, whichever branch each request goes to. It is separate from your corporate team's other API tokens, which keep their own limit. Responses carry
X-RateLimit-Context: enterprise:default. See Rate Limiting. If you're syncing data across many branches and need more, contact support to raise it. - Circuit breaker. If calls to one branch keep failing (for example because its subscription lapsed), requests to that branch are paused for a few minutes (
429withX-Throttle-Reason: circuit_breaker). Other branches are unaffected. - Retries. A retried
POSTwith an identical body to the same branch within 30 seconds is treated as a duplicate and returns the original response.
Who Changes Are Recorded Under
Requests made with an enterprise token act as the branch's owner (its longest-standing owner, or an admin if it has no owner). Anything created without an explicit owner, such as a contact with no assignedUserId or a task with no assignee, is recorded under that person, just as it would be with a Team token they created. The token and the person who created it are kept in the change history, so every change can be traced back to your integration.
FAQ
Can I use a branch's id as teamId for a branch that joins the enterprise later?
Yes. New branches appear in GET /api/partner/teams as soon as they're added to the enterprise, and leaving the enterprise removes them immediately.
Can a branch or region get its own enterprise token?
No. Enterprise tokens can only be created on the corporate team. A single branch can use a regular Team token.
Can an enterprise token read contacts, loans or other branch data?
Yes. The enterprise owns every branch and its data, so an enterprise token can work with any of it, one branch at a time (with teamId) and only with the matching permission. Loans, contracts and other endpoints without their own permission need full_access. As with any API token, grant only what the integration needs.
Can I search contacts across every branch at once?
No. Only the teams and users lookups span the enterprise; for everything else, call each branch with its teamId.
Do the loan pipeline and reports for the corporate team or a region include its branches?
No. With an enterprise token they cover only the team named by teamId, even where a person viewing the corporate team or a region in the app would see a rollup. To build an enterprise-wide view, call each team and combine the results; nothing is counted twice.
What if a user is on several branches?
Their teams lists all of them. Sure Send never guesses the branch, so your integration chooses one and sends it as teamId.
Updated about 18 hours ago
