Getting started

Authentication

Authenticate with API keys, limit them to some profiles, make them read-only or bar whole areas of the API, and rotate them safely.

Every request to https://api.pozy.ai/v1 carries a bearer credential in the Authorization header. For your own servers that credential is an API key. The MCP server signs in with OAuth, and the dashboard uses your browser session. All of them hit the same API with the same rules.

Terminal
curl https://api.pozy.ai/v1/accounts \
  -H "Authorization: Bearer $POZY_API_KEY"

#API keys

A key looks like pz_live_ followed by 64 hex characters. It belongs to the workspace, not to the person who created it, so it keeps working when that member leaves.

Pozy stores only a SHA-256 hash of each key. The full value is returned once, when you create it. Lists show a preview such as pz_live_3f9a...c41e so you can tell keys apart.

Keep keys on the server

A key can do anything its settings allow, including publishing and spending money on ads, numbers and messages. Never ship one in a mobile app, a browser bundle or a public repository. If one leaks, delete it at once and create a new one.

#Create a key in the dashboard

Open API keys, click Create key, pick a name and the settings below, and copy the value. Workspace owners and admins can create keys.

#Create a key with the API

POST /v1/api-keys creates a key from code, for example when you onboard a customer and want a key that only reaches their profile. The call needs a full-access, read-write key (or an owner or admin session).

curl -X POST https://api.pozy.ai/v1/api-keys \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Reporting job",
    "permission": "read",
    "disabledResourceGroups": ["billing", "webhooks"],
    "expiresIn": 90
  }'
Response (201)
{
  "message": "API key created",
  "apiKey": {
    "id": "key_Vb3nQ8rT1xLm6Zc0Wp9s",
    "name": "Reporting job",
    "key": "pz_live_3f9a0c7e...",
    "keyPreview": "pz_live_3f9a...c41e",
    "scope": "full",
    "profileIds": [],
    "permission": "read",
    "disabledResourceGroups": ["billing", "webhooks"],
    "expiresAt": "2027-01-28T10:12:44.000Z",
    "createdAt": "2026-10-30T10:12:44.000Z"
  }
}

#Key settings

Field Values Default Effect
name text required Label shown in lists and logs.
scope full, profiles full profiles limits the key to the profiles in profileIds.
profileIds profile ids none Required when scope is profiles. Every id must belong to the workspace.
permission read-write, read read-write read allows only GET requests.
disabledResourceGroups group names none Areas of the API the key may not call. See the table below.
expiresIn days never expires The key stops working after that many days.

#Profile-scoped keys

A key with scope: "profiles" is limited to the profiles you list. Any request that names a profile outside that list, in the path, the query string or the body, fails with 403 and code: "profile_out_of_scope". A request that names an account (accountId, accountIds, targetAccountId or sourceAccountId) belonging to another profile fails with 403 and code: "account_out_of_scope". GET /v1/profiles returns only the profiles in scope.

Use one per customer when you build a platform, so a bug or a leaked key in one tenant cannot touch another. With a scoped key, always pass profileId on list calls (accounts, posts, conversations) so results stay inside the tenant.

Scoped keys cannot manage API keys, and they cannot read workspace-wide billing. Calls that need the whole workspace return 403 with code: "profile_scoped_key".

#Read-only keys

With permission: "read", any request other than GET fails before it runs:

403
{
  "error": "This credential is read-only.",
  "type": "permission_error",
  "code": "read_only_key"
}

Give read-only keys to dashboards, reporting jobs, BI tools and AI assistants that only need to look.

#Disabled resource groups

Every endpoint belongs to one resource group. A key with a group in disabledResourceGroups gets 403 with code: "resource_group_disabled" on any endpoint in that group, read or write.

Group Covers
publishing Posts, queues, validation tools, media uploads, blog articles
engagement Comments, reviews, mentions, likes and reposts, Discord server actions, Google Business reviews
messages DMs and conversations, broadcasts, sequences, comment-to-DM, WhatsApp and RCS messages, email, voice agents
contacts Contacts, custom field values, ad lead forms and leads, WhatsApp blocked users
analytics Post, account and inbox analytics
ads Ad accounts, campaigns, ad sets, creatives, audiences, conversions, pixels, catalogs, rules, insights
telephony Phone numbers, SMS, voice calls, branded calling, WhatsApp numbers and calling, verification codes
accounts Connect flows, connected accounts, profiles, account groups, account settings, workflows, WhatsApp templates and flows, Google Business locations
billing Usage and billing
webhooks Webhook endpoints, delivery logs, test deliveries
commerce Stores, products, orders and other commerce data
creator_campaigns Creator campaigns, participants and submissions
money Balance, top-ups, payees and transfers
calendar Calendar events
files Files

The API reference shows each endpoint's group under Authentication.

Least privilege

Start from the narrowest key that works. A scheduling backend needs publishing and accounts, so it can disable ads, telephony, money, billing and webhooks. A support inbox needs messages, engagement and contacts.

#Rotate and revoke keys

Deleting a key revokes it immediately. Requests that use it start failing with 401 on the next call.

To rotate without downtime:

  1. Create the new key with the same settings.
  2. Deploy it everywhere the old key is used.
  3. Check the old key's Last used time in the dashboard. Once it stops moving, delete it.
curl -X DELETE https://api.pozy.ai/v1/api-keys/key_Vb3nQ8rT1xLm6Zc0Wp9s \
  -H "Authorization: Bearer $POZY_API_KEY"

#Check a credential

GET /v1/auth/verify returns valid: true with the credential type (api_key, oauth or session), its scope and the workspace it belongs to. Use it in health checks and when you debug a 401 or 403.

#OAuth for the MCP server

The MCP server at https://mcp.pozy.ai/mcp signs you in through the browser with your Pozy account. It acts as you, so your workspace role applies: a viewer gets read-only access, and a member cannot manage keys, webhooks or billing. You can revoke these sessions from Settings → Connected apps in the dashboard. Clients that cannot do OAuth can send an API key as the bearer token instead.

#Dashboard sessions

The dashboard calls the same public API with your session cookie. Write requests from another site are refused with code: "csrf_rejected", so a session cannot be used from a page you do not trust. Dashboard traffic has its own rate limit budget, 120 requests a minute per workspace, and does not eat into your keys' limit.

#Errors you may see

Status code Meaning Fix
401 invalid_api_key Missing, mistyped, revoked or expired credential. Check the Authorization: Bearer header and the key's expiry.
403 read_only_key A write with a read-only key. Use a read-write key.
403 resource_group_disabled The endpoint's group is disabled on this key. Use a key that allows the group.
403 insufficient_permissions The key type cannot do this, for example a scoped or read-only key managing keys. Use a full-access, read-write key.
403 role_forbidden Your workspace role cannot do this (sessions and OAuth tokens). Ask an owner or admin for a different role.
403 profile_out_of_scope A profile-scoped key named a profile it does not cover. Use a key scoped to that profile.
403 account_out_of_scope A profile-scoped key named an account that belongs to another profile. Check the account id, or use a key scoped to that account's profile.
403 profile_scoped_key A profile-scoped key called a workspace-wide endpoint. Pass a profileId where the endpoint accepts one, or use a full-access key.
403 feature_not_available The feature is not enabled for the workspace. Contact support@pozy.ai.

#Endpoints

Endpoint What it does
GET /v1/auth/verify Verify credential
GET /v1/api-keys List keys
POST /v1/api-keys Create key
DELETE /v1/api-keys/{keyId} Delete key