Skip to content

Public API Guide

This guide walks you through getting API credentials, authenticating, and making your first calls against the PartnerPortal REST API.

For the high-level overview of your integration options, see Developer Documentation. For real-time event notifications, see the Webhooks Guide.

The REST API is lead- and partner-centric. With it you can:

  • Sync leads both ways by creating, updating, fetching, and listing leads
  • Discover your schema so your integration maps the right standard fields, custom fields, and picklist values
  • Bulk-import partner users into partner organizations that already exist in your portal
  • Receive real-time events via webhooks such as lead/create, lead/update, and lead/delete
  • Automate without code via Zapier

Not available via the API today:

  • creating new partner organizations
  • a general content / document / resource library sync
  • broad bulk operations with a self-serve key

Bulk endpoints require a user-delegated token, not the self-serve keys you generate in the portal. Everything else in this guide works with a self-serve key. If you need server-to-server bulk imports, contact [email protected].

A quick terms note: a lead is a deal or opportunity referred by a partner, a partner organization is a partner company in your portal, and an agent is the partner user credited for a lead.

If your plan includes API access, you can create and manage your own API keys directly in your portal.

  1. In your portal, go to Portal Setup → Other → Developer / API Keys.
  2. Click Create API Key, give it a recognizable name, and confirm.
  3. Copy the Client ID and Client Secret that are shown.

The Client Secret is shown only once. Copy it immediately and store it somewhere secure. If you lose it, revoke the key and create a new one.

You will also need:

  • Audience: https://api.partnerportal.io for production
  • Company ID: the 24-character identifier for your portal

From the same Developer / API Keys page, click Revoke next to any key.

Revocation takes effect promptly, although an already-issued token may continue working until it expires.

Do not see the Developer / API Keys section? API access may not be included on your current plan, or you may not have admin permissions. Contact [email protected].

The keys you generate are machine-to-machine credentials. They authenticate your server, not an individual user, and are the recommended way to build a backend integration.

The same credentials work for both the REST API and Webhooks.

The API uses OAuth 2.0. Before calling any endpoint, exchange your Client ID and Client Secret for a short-lived access token.

Terminal window
curl -X POST "https://login.partnerportal.io/oauth/token" \
-H "content-type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"audience": "https://api.partnerportal.io"
}'

You will get back JSON containing an access_token.

Cache that token and reuse it until it is close to expiry instead of requesting a new one for every call.

Include it in the Authorization header of every request:

Authorization: Bearer YOUR_ACCESS_TOKEN

The simplest way to confirm everything is wired up is to fetch your lead schema.

Terminal window
curl "https://api.partnerportal.io/1.0/api/company/YOUR_COMPANY_ID/schema/lead" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

A JSON response with a unifiedFields array means you are set up correctly. Each entry tells you the field’s fieldId, label, type, whether it is required, and whether it is creatable or updateable.

If you get a 401 or 403, check that:

  • your access-token request returned 200
  • you are using the access token, not the Client Secret, as the Bearer value
  • you included the header as Authorization: Bearer ...
  • you used the right audience for your environment
  • the key has not been revoked

All REST endpoints live under:

https://api.partnerportal.io/1.0/api

Non-production environments use:

https://api.partnerportal.dev/1.0/api
Terminal window
curl -X POST "https://api.partnerportal.io/1.0/api/company/YOUR_COMPANY_ID/leads" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Jane",
"lastName": "Smith",
"platform": "Enterprise",
"email": "[email protected]",
"partnerOrganizationId": "PARTNER_ORG_ID",
"agentId": "AGENT_ID"
}'

A successful create returns the created lead, including its new id. Store that id, since that is how you will match incoming webhooks and fetch the lead later.

{
"id": "66a1f2c9e4b0a1234567890a",
"companyId": "YOUR_COMPANY_ID",
"firstName": "Jane",
"lastName": "Smith",
"platform": "Enterprise",
"email": "[email protected]",
"partnerOrganizationId": "PARTNER_ORG_ID",
"agentId": "AGENT_ID",
"status": "pending",
"value": 50000,
"createdAt": "2026-06-29T19:00:00.000Z",
"updatedAt": "2026-06-29T19:00:00.000Z"
}

Required fields vary by portal, so always call GET /schema/lead first and treat each field with required: true as mandatory.

If you are using a self-serve key, partnerOrganizationId and agentId are also required on create, and the agentId must belong to the given partnerOrganizationId.

Picklist values must come from your schema rather than from an arbitrary string.

The calls above reference a few IDs:

  • companyId is the 24-character identifier for your portal
  • partnerOrganizationId and agentId can be discovered from existing leads you read back from the API
  • if you have a brand-new portal with no leads or partners yet, contact [email protected] for a starting pair

Custom fields go under a customFields object keyed by the fieldId from your schema:

{
"firstName": "Jane",
"lastName": "Smith",
"platform": "Enterprise",
"customFields": {
"<fieldId>": "value"
}
}
Terminal window
curl "https://api.partnerportal.io/1.0/api/company/YOUR_COMPANY_ID/leads/LEAD_ID" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

This is the standard follow-up after receiving a webhook.

Terminal window
curl -X PATCH "https://api.partnerportal.io/1.0/api/company/YOUR_COMPANY_ID/leads/LEAD_ID" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "value": 50000 }'
Terminal window
curl "https://api.partnerportal.io/1.0/api/company/YOUR_COMPANY_ID/leads" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Use this to pull historical data or reconcile your copy against the portal.

  1. Subscribe to the lead/create webhook topic.
  2. When a webhook arrives, verify the signature and read the lead id.
  3. Call GET /company/YOUR_COMPANY_ID/leads/{id} to fetch the full record.
  4. Save it in your system, using topic + id + timestamp as a deduplication key.
  1. Pull your schema once at setup with GET /schema/lead.
  2. For each lead, POST /company/YOUR_COMPANY_ID/leads with the mapped body.

Webhooks are forward-looking. To pull historical data or catch anything missed during an outage, periodically list leads and diff against your local copy.

  • cache your access token and refresh it only as it nears expiry
  • be reasonable with request volume and back off if you receive a 429
  • verify webhook signatures instead of trusting source IPs
  • rotate keys you no longer use and revoke immediately if a secret may have leaked

If you run into auth errors, unexpected responses, or design questions, contact [email protected].