Summary and recommendation
The PartnerStack REST API (v2) is available at https://api.partnerstack.com/api/v2 and authenticates via HTTP Basic Auth - Public Key as username, Secret Key as password, Base64-encoded in the Authorization header.
There is no OAuth flow and no bearer token model.
The API is scoped primarily to partner and customer data, transactions, and program (group) membership;
internal team member provisioning is not exposed via API.
Pagination is cursor-based using `starting_after` and `limit` params, with a maximum page size of 100.
Rate limits are enforced but thresholds are not publicly documented - implement exponential backoff on 429 responses.
API quick reference
| Has user API | Yes |
| Auth method | HTTP Basic Auth (API key as username, secret as password) |
| Base URL | Official docs |
| SCIM available | No |
Authentication
Auth method: HTTP Basic Auth (API key as username, secret as password)
Setup steps
- Log in to your PartnerStack account and navigate to Settings > Integrations > API.
- Generate a Public Key (username) and Secret Key (password).
- Base64-encode the string 'public_key:secret_key'.
- Pass the encoded value in the Authorization header as: 'Authorization: Basic
'.
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| customer_key | string | Unique identifier for the customer/user in PartnerStack. | required | immutable | Used as the primary key for customer objects. |
| string | Email address of the partner or customer. | required | optional | Must be unique within the program. | |
| name | string | Full name of the partner or customer. | optional | optional | |
| first_name | string | First name of the partner. | optional | optional | |
| last_name | string | Last name of the partner. | optional | optional | |
| partner_key | string | Unique identifier for the referring partner. | optional | read-only | Links a customer to the partner who referred them. |
| created_at | integer | Unix timestamp of when the record was created. | system-set | immutable | |
| updated_at | integer | Unix timestamp of the last update. | system-set | system-set | |
| status | string | Status of the partner account (e.g., active, inactive). | optional | optional | |
| external_key | string | Your internal identifier for the customer, used for deduplication. | optional | optional | Useful for mapping PartnerStack records to your own system. |
| metadata | object | Arbitrary key-value pairs for custom data. | optional | optional | |
| group_key | string | Identifier for the partner group/program the partner belongs to. | optional | optional |
Core endpoints
List Partners
- Method: GET
- URL:
https://api.partnerstack.com/api/v2/partners - Watch out for: Pagination uses cursor-based 'starting_after' param, not page numbers.
Request example
GET /api/v2/partners?limit=25 HTTP/1.1
Host: api.partnerstack.com
Authorization: Basic <base64_credentials>
Response example
{
"data": {
"items": [{"key": "prt_abc123", "email": "partner@example.com", "name": "Jane Doe"}],
"has_more": false,
"ending_cursor": "cursor_xyz"
}
}
Get Partner
- Method: GET
- URL:
https://api.partnerstack.com/api/v2/partners/{partner_key} - Watch out for: Use the PartnerStack-assigned partner_key, not email, as the path parameter.
Request example
GET /api/v2/partners/prt_abc123 HTTP/1.1
Host: api.partnerstack.com
Authorization: Basic <base64_credentials>
Response example
{
"data": {
"key": "prt_abc123",
"email": "partner@example.com",
"name": "Jane Doe",
"status": "active"
}
}
Create Customer
- Method: POST
- URL:
https://api.partnerstack.com/api/v2/customers - Watch out for: customer_key must be unique; duplicate submissions return an error rather than upsert.
Request example
POST /api/v2/customers HTTP/1.1
Host: api.partnerstack.com
Authorization: Basic <base64_credentials>
Content-Type: application/json
{"customer_key":"cust_001","email":"user@example.com","partner_key":"prt_abc123"}
Response example
{
"data": {
"key": "cust_001",
"email": "user@example.com",
"partner_key": "prt_abc123",
"created_at": 1700000000
}
}
Update Customer
- Method: PUT
- URL:
https://api.partnerstack.com/api/v2/customers/{customer_key} - Watch out for: customer_key in the path is your external key, not a PartnerStack-generated key.
Request example
PUT /api/v2/customers/cust_001 HTTP/1.1
Host: api.partnerstack.com
Authorization: Basic <base64_credentials>
Content-Type: application/json
{"email":"newemail@example.com"}
Response example
{
"data": {
"key": "cust_001",
"email": "newemail@example.com"
}
}
List Customers
- Method: GET
- URL:
https://api.partnerstack.com/api/v2/customers - Watch out for: Max page size is 100; use ending_cursor as starting_after for next page.
Request example
GET /api/v2/customers?limit=50 HTTP/1.1
Host: api.partnerstack.com
Authorization: Basic <base64_credentials>
Response example
{
"data": {
"items": [{"key": "cust_001", "email": "user@example.com"}],
"has_more": true,
"ending_cursor": "cursor_abc"
}
}
Create Transaction (for commission tracking)
- Method: POST
- URL:
https://api.partnerstack.com/api/v2/transactions - Watch out for: Amount is in cents (integer). Transactions trigger commission calculations for the linked partner.
Request example
POST /api/v2/transactions HTTP/1.1
Host: api.partnerstack.com
Authorization: Basic <base64_credentials>
Content-Type: application/json
{"customer_key":"cust_001","amount":9900,"currency":"usd"}
Response example
{
"data": {
"key": "txn_xyz",
"customer_key": "cust_001",
"amount": 9900,
"status": "pending"
}
}
Get Group (Program)
- Method: GET
- URL:
https://api.partnerstack.com/api/v2/groups/{group_key} - Watch out for: Groups correspond to partner programs; partners are scoped to a group.
Request example
GET /api/v2/groups/grp_abc123 HTTP/1.1
Host: api.partnerstack.com
Authorization: Basic <base64_credentials>
Response example
{
"data": {
"key": "grp_abc123",
"name": "Affiliate Program",
"slug": "affiliate"
}
}
List Partnerships (Partner-Group memberships)
- Method: GET
- URL:
https://api.partnerstack.com/api/v2/partnerships - Watch out for: A partner can have memberships in multiple groups; filter by group_key to scope results.
Request example
GET /api/v2/partnerships?limit=25 HTTP/1.1
Host: api.partnerstack.com
Authorization: Basic <base64_credentials>
Response example
{
"data": {
"items": [{"partner_key": "prt_abc123", "group_key": "grp_abc123", "status": "active"}],
"has_more": false
}
}
Rate limits, pagination, and events
Rate limits: PartnerStack enforces rate limits but does not publicly document specific request-per-minute or per-tier thresholds in official docs as of the last known update.
Rate-limit headers: Unknown
Retry-After header: Unknown
Rate-limit notes: No explicit rate limit values, headers, or Retry-After behavior documented in official sources. Contact PartnerStack support for current limits.
Pagination method: cursor
Default page size: 25
Max page size: 100
Pagination pointer: starting_after / limit
Webhooks available: Yes
Webhook notes: PartnerStack supports webhooks to notify your system of events such as new partner sign-ups, customer creation, and transaction status changes. Webhooks are configured in the PartnerStack dashboard under Settings > Integrations > Webhooks.
Alternative event strategy: Poll the REST API endpoints if webhook delivery is not suitable for your use case.
Webhook events: partner.created, partner.updated, customer.created, customer.updated, transaction.created, transaction.updated, reward.created
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: Not documented
- Endpoint: Not documented
Limitations:
- PartnerStack does not offer a native SCIM 2.0 endpoint for identity provider provisioning.
- No documented IdP (Okta, Entra, Google Workspace, OneLogin) SCIM connector support found in official sources.
Common scenarios
Three high-value automation scenarios emerge from the available endpoints.
First, customer attribution: capture partner_key from the referral click, then POST to /api/v2/customers with your customer_key, email, and partner_key at signup note that duplicate customer_key values return an error, not an upsert.
Second, commission triggering: POST to /api/v2/transactions with customer_key, amount (integer, in cents), and currency on billing events;
transactions start in pending and require approval before payout, so listen for the transaction.updated webhook to confirm status transitions.
Third, partner program auditing: GET /api/v2/partnerships?group_key=<key>&limit=100, paginate via ending_cursor until has_more is false, then optionally hydrate each record with GET /api/v2/partners/{partner_key}
omitting group_key returns all partnerships across all programs and can produce a large, unscoped dataset.
Attribute a new customer to a referring partner
- Capture the partner's referral link click and extract the partner_key from the URL or cookie.
- When the customer signs up in your system, POST to /api/v2/customers with customer_key (your ID), email, and the captured partner_key.
- PartnerStack links the customer to the partner for commission tracking.
Watch out for: If customer_key already exists, the POST will fail. Check for existing customers first or use a deterministic key scheme.
Record a subscription renewal to trigger partner commission
- On renewal event in your billing system, POST to /api/v2/transactions with customer_key, amount (in cents), and currency.
- PartnerStack calculates the commission for the partner linked to that customer.
- Listen for the transaction.updated webhook to confirm the transaction status transitions to 'approved'.
Watch out for: Transactions in 'pending' status do not immediately pay out; they must be approved either automatically (based on program rules) or manually in the dashboard.
Audit all active partners in a program
- GET /api/v2/partnerships?group_key=
&limit=100 to retrieve partner memberships. - Use ending_cursor as starting_after in subsequent requests until has_more is false.
- For each partner_key returned, optionally GET /api/v2/partners/{partner_key} for full profile details.
Watch out for: Filtering partnerships by group_key scopes results to one program; omitting it returns all partnerships across all programs, which may be a large dataset.
Why building this yourself is a trap
The API's identity graph is shallow on the vendor/internal-user side: there are no endpoints to invite, update, or deprovision internal team members programmatically. The graph covers partners (partner_key), customers (customer_key as your external ID plus PartnerStack's internal key - track both), and group memberships (group_key), but stops there.
Teams building identity automation pipelines via an MCP server with 60+ deep IT/identity integrations should treat PartnerStack as a one-directional data source for partner and revenue data, not a full identity node.
The absence of SCIM 2.0 and any documented IdP connector (Okta, Entra, Google Workspace, OneLogin) means lifecycle events for internal users cannot be automated from your IdP - a hard architectural constraint, not a configuration gap.
Automate PartnerStack workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.