Authentication
Every request must include an OAuth 2.0 Bearer token:
Authorization: Bearer <token>
The token identifies one tenant (business_id) and one acting user. You never pass
business_id in the URL — it's derived from the token. There is no concept of a request that spans
tenants.
Choosing a flow
| You are… | Use | Token type |
|---|---|---|
| A backend service / script acting as the tenant | Personal Access Token (PAT) — client-credentials | bearerPat |
| A marketplace / third-party app acting on behalf of a user | Authorization Code + PKCE | oauth2 |
Personal Access Token (server-to-server)
A PAT is the fastest way to start. Issue one per tenant and treat it like a password — it grants the scopes you select at creation time.
curl https://papi.trendev.in/v1/contacts/con_8f2a1c9b4d6e7f0a1b2c3d4e \
-H "Authorization: Bearer $PROSPECTCONNECT_TOKEN" \
-H "Version: 2026-06-01"
Authorization Code + PKCE (apps acting for a user)
For apps that act on behalf of an end user, run the standard OAuth 2.1 authorization-code flow with PKCE:
- Redirect the user to
https://auth.prospectconnect.ai/authorizewith yourclient_id,redirect_uri,response_type=code,code_challenge(S256), and thescopes you need. - Exchange the returned
codeathttps://auth.prospectconnect.ai/token(with yourcode_verifier) for an access token + refresh token. - Call the API with the access token; refresh it when it expires.
Dynamic Client Registration (RFC 7591) is supported, so apps can register programmatically.
Scopes
Scopes are <resource>.<action>. Request the least you need.
| Resource | read | write | delete | all |
|---|---|---|---|---|
contact | ✓ | ✓ | ✓ | full access |
company | ✓ | ✓ | ✓ | full access |
deal | ✓ | ✓ | ✓ | full access |
task | ✓ | ✓ | ✓ | full access |
note | ✓ | ✓ | ✓ | full access |
activity | ✓ | ✓ | ✓ | full access |
read—GETandPOST /search.write— create +PATCH+ action paths (e.g. change a deal's stage, complete a task, pin a note).delete—DELETE.all— everything for that resource.
Each endpoint in the API Reference lists the exact scope it requires.
Scope ∩ role — the part that surprises people
A token's scopes are only half the check. The API also enforces the acting user's role and feature permissions in the CRM, and applies the intersection:
Effective permission = OAuth scope ∧ the user's role/permissions.
So a token with contact.delete still gets 403 if the user behind it isn't allowed to delete
contacts in the CRM. This is deliberate — it means the public API and the co-pilot can never be used to
exceed what the user could do in the product UI. Design your integration around the user's real
permissions, not just the scopes you asked for.