API reference
Partner Hub Management API
Manage reseller relationships, product assignments, serial inventory and conversations with developer workspace authentication.
Choose the correct partner surface
Relationship operations are first-party developer workspace calls authenticated with an account Bearer token. They require partners.view and all-products scope; writes additionally require partners.manage. Serial-pool export also requires partners.manage. The separate product promo-kit operations require partners.manage and assigned-product access even for GET, without requiring all-products scope. An external reseller must use its approved partner integration, not a developer account token.
Relationship discovery, requests, decisions, assignments, serial pools and conversations are separate from external order fulfillment and money movement. A saved commercial term or serial allocation does not prove a sale, collected payment, tax remittance or payout. SoundSync covers processing costs on SoundSync-managed checkout, not an external reseller sale.
Request a relationship, then assign products
Read the reseller directory and existing relationships before requesting one with partnerId. An existing relationship can be returned rather than duplicated. Accept or deny only an eligible request. Pausing/resuming a relationship is not the same as deleting products or refunding customer orders.
Product assignment uses a catalog product ID; later PATCH/DELETE uses the assignment record ID. Review supported SKUs, commercial terms and basis-point shares before saving. Assignment does not grant every product in the workspace. Allocate serial inventory only after checking the active relationship, product eligibility and supported pool rules; reconcile an uncertain allocation before retrying.
Keep conversations and serial exports private
Start a thread with subject and body/message; reply using the thread ID within the same relationship. Message responses return a thread or message wrapper. Thread message pages report has_more, limit and offset. Never include customer passwords, tokens or full serials in messages.
Serial-pool export returns a private CSV attachment with one serial license per line and no header, quotation marks or other columns. Keep it out of screenshots, public links and logs. Allocation is inventory, not evidence that each key was sold or redeemed.
Read reporting without mistaking estimates for payments
The overview covers the current month, sales-analytics groups reported amounts by currency, and hub-records pages orders, licenses, conversations, campaigns or statements. pool-estimates and serial-pools describe allocated reseller inventory. Historical orders, customers, licenses, statements, settings and API-health have their own read operations.
These records can include private identity, serials and commercial terms. Reported external sales and expected payables are not funded SoundSync checkout earnings. API-health reports saved key configuration and 30-day request statistics, not a real-time connection guarantee.
Edit commercial terms and partner deals deliberately
The terms action saves relationship-level commercial, visibility and supported capability settings; settings PATCH routes are compatible aliases. Share percentages are expressed in basis points. Suspending or ending a relationship does not refund external payments or erase historical records.
Partner campaigns are reseller scheduled deals, not email campaigns. Both create and edit require a name. Campaign PATCH replaces normalized descriptive fields: omitted status becomes draft, and omitted dates, notes and description can be cleared. Read the current record and send the complete intended details. An optional product must already be assigned to the relationship.
Prepare a product promo kit
Use promo-kit to share approved descriptive copy, feature bullets, suggested prices, license terms and promotional media references for an assigned product. Its PUT replaces kit content; read and preserve intended fields before saving. Asset PATCH retains omitted fields, while DELETE removes the reference rather than promising physical deletion of a hosted file.
Use media you have the right to distribute. A URL/storage-key reference is not a binary upload or authorized customer download. A promo-kit price suggestion does not change checkout prices; artwork in the kit is separate from marketplace approval and website artwork preferences.
SoundSync
Retired Partner Hub fulfillment writes
| Developer workspace path | Current result |
|---|---|
| POST /api/developer/partners/{relationshipId}/orders | 410 PARTNER_FULFILLMENT_DISABLED; authorized historical GET reads remain separate. |
| POST /api/developer/partners/resellers/{relationshipId}/orders | 410 PARTNER_FULFILLMENT_DISABLED; not the external partner order API. |
| POST /api/developer/partners/resellers/{relationshipId}/api-keys and /api-keys/{keyId}/rotate or /revoke | 410 PARTNER_FULFILLMENT_DISABLED on these legacy workspace writes; not a claim that all partner integrations are disabled. |
| POST /api/developer/partners/resellers/{relationshipId}/statements/generate and PATCH /statements/{statementId} | 410 PARTNER_FULFILLMENT_DISABLED; historical reports are not payout execution. |
SoundSync
External integrations and payout reporting
SoundSync
Requests and responses
/api/developer/partners/directory/resellers
Browse the eligible reseller directory
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope.
- Returns
- HTTP 200: resellers.
- Notes
- partners.view and all-products workspace scope. Relationship and product ownership checks still apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"resellers": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers
List developer reseller relationships
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope.
- Returns
- HTTP 200: relationships.
- Notes
- partners.view and all-products workspace scope. Relationship and product ownership checks still apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"relationships": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}
Read an owned reseller relationship
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope.
- Returns
- HTTP 200: relationship.
- Notes
- partners.view and all-products workspace scope. Relationship and product ownership checks still apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"relationship": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/requests
Request a developer-reseller relationship
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope. Writes additionally require partners.manage.
- Request fields
- partnerId: integer
- partner_id: integer
- message: string
- reason: string
- note: string
- Returns
- HTTP 201: relationship.
- Notes
- partners.view and all-products workspace scope. Writes additionally require partners.manage. Relationship and product ownership checks still apply. Creates a relationship request, not approval or permission to sell every product.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"partnerId": {
"type": "integer",
"minimum": 1
},
"partner_id": {
"type": "integer",
"minimum": 1
},
"message": {
"type": "string"
},
"reason": {
"type": "string"
},
"note": {
"type": "string"
}
},
"additionalProperties": true,
"anyOf": [
{
"required": [
"partnerId"
]
},
{
"required": [
"partner_id"
]
}
]
}
HTTP 201 response (application/json)
{
"type": "object",
"properties": {
"relationship": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers/{relationshipId}/accept
Accept an eligible reseller request
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope. Writes additionally require partners.manage.
- Request fields
- reason: string
- Returns
- HTTP 200: relationship.
- Notes
- partners.view and all-products workspace scope. Writes additionally require partners.manage. Relationship and product ownership checks still apply. The current request side and status must allow this decision. Re-read state after a conflict.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"reason": {
"type": "string"
}
},
"additionalProperties": true
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"relationship": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers/{relationshipId}/deny
Deny a reseller request
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope. Writes additionally require partners.manage.
- Request fields
- reason: string
- Returns
- HTTP 200: relationship.
- Notes
- partners.view and all-products workspace scope. Writes additionally require partners.manage. Relationship and product ownership checks still apply. The current request side and status must allow this decision. Re-read state after a conflict.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"reason": {
"type": "string"
}
},
"additionalProperties": true
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"relationship": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/pause
Set the relationship to paused
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope. Writes additionally require partners.manage.
- Returns
- HTTP 200: relationship.
- Notes
- partners.view and all-products workspace scope. Writes additionally require partners.manage. Relationship and product ownership checks still apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"relationship": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/resume
Set the relationship to active
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope. Writes additionally require partners.manage.
- Returns
- HTTP 200: relationship.
- Notes
- partners.view and all-products workspace scope. Writes additionally require partners.manage. Relationship and product ownership checks still apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"relationship": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/products
List assigned relationship products
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope.
- Returns
- HTTP 200: products.
- Notes
- partners.view and all-products workspace scope. Relationship and product ownership checks still apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"products": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/products/assign
Assign or approve an owned product for this relationship
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope. Writes additionally require partners.manage.
- Request fields
- productId: integer
- product_id: integer
- status: string
- resellerSku: string
- reseller_sku: string
- resellerProductName: string
- commercialModel: string
- commissionRateBps: integer
- developerRevenueShareBps: integer
- currency: string
- minimumAdvertisedPriceCents: integer
- licenseCap: integer
- monthlyLicenseCap: integer
- apiEnabled: boolean
- manualIssueEnabled: boolean
- staticExportEnabled: boolean
- metadata: object. Operation-specific extension data; do not put credentials or unnecessary personal information here.
- Returns
- HTTP 201: product.
- Notes
- partners.view and all-products workspace scope. Writes additionally require partners.manage. Relationship and product ownership checks still apply. Supported snake-case commercial fields are also accepted. Commission/share fields are basis points. This saves an assignment; it does not create a sale, license claim or payout. Review commercial terms before saving.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"productId": {
"type": "integer",
"minimum": 1
},
"product_id": {
"type": "integer",
"minimum": 1
},
"status": {
"type": "string"
},
"resellerSku": {
"type": "string"
},
"reseller_sku": {
"type": "string"
},
"resellerProductName": {
"type": "string"
},
"commercialModel": {
"type": "string"
},
"commissionRateBps": {
"type": "integer"
},
"developerRevenueShareBps": {
"type": "integer"
},
"currency": {
"type": "string"
},
"minimumAdvertisedPriceCents": {
"type": "integer"
},
"licenseCap": {
"type": "integer"
},
"monthlyLicenseCap": {
"type": "integer"
},
"apiEnabled": {
"type": "boolean"
},
"manualIssueEnabled": {
"type": "boolean"
},
"staticExportEnabled": {
"type": "boolean"
},
"metadata": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true,
"anyOf": [
{
"required": [
"productId"
]
},
{
"required": [
"product_id"
]
}
]
}
HTTP 201 response (application/json)
{
"type": "object",
"properties": {
"product": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/products/{assignmentId}
Update the saved product assignment
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope. Writes additionally require partners.manage.
- Request fields
- productId: integer
- product_id: integer
- status: string
- resellerSku: string
- reseller_sku: string
- resellerProductName: string
- commercialModel: string
- commissionRateBps: integer
- developerRevenueShareBps: integer
- currency: string
- minimumAdvertisedPriceCents: integer
- licenseCap: integer
- monthlyLicenseCap: integer
- apiEnabled: boolean
- manualIssueEnabled: boolean
- staticExportEnabled: boolean
- metadata: object. Operation-specific extension data; do not put credentials or unnecessary personal information here.
- Returns
- HTTP 200: product.
- Notes
- partners.view and all-products workspace scope. Writes additionally require partners.manage. Relationship and product ownership checks still apply. assignmentId is the relationship-product record, not the catalog product ID. Omitted saved fields are retained; reload the assignment before editing commercial terms.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"productId": {
"type": "integer",
"minimum": 1
},
"product_id": {
"type": "integer",
"minimum": 1
},
"status": {
"type": "string"
},
"resellerSku": {
"type": "string"
},
"reseller_sku": {
"type": "string"
},
"resellerProductName": {
"type": "string"
},
"commercialModel": {
"type": "string"
},
"commissionRateBps": {
"type": "integer"
},
"developerRevenueShareBps": {
"type": "integer"
},
"currency": {
"type": "string"
},
"minimumAdvertisedPriceCents": {
"type": "integer"
},
"licenseCap": {
"type": "integer"
},
"monthlyLicenseCap": {
"type": "integer"
},
"apiEnabled": {
"type": "boolean"
},
"manualIssueEnabled": {
"type": "boolean"
},
"staticExportEnabled": {
"type": "boolean"
},
"metadata": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"product": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/products/{assignmentId}
Remove the supported product assignment
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope. Writes additionally require partners.manage.
- Returns
- HTTP 200: product.
- Notes
- partners.view and all-products workspace scope. Writes additionally require partners.manage. Relationship and product ownership checks still apply. Does not issue a refund or erase customer payment history.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"product": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/serials
Read relationship serial inventory
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope.
- Returns
- HTTP 200: serials.
- Notes
- partners.view and all-products workspace scope. Relationship and product ownership checks still apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"serials": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/serials/allocate
Allocate product serial inventory
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope. Writes additionally require partners.manage.
- Request fields
- productId: integer
- product_id: integer
- relationshipProductId: integer
- quantity: integer
- batchLabel: string
- notes: string
- fulfillmentMode: "generated_serials"
- prefix: string
- price: number
- price_cents: integer
- sale_price: number
- sale_price_cents: integer
- expiresAt: string,null
- autoRevokeUnusedOnExpiry: boolean
- promoStart: string,null
- promoExpires: string,null
- Returns
- HTTP 201: pool, allocation, quantity, count, items_created, serials.
- Notes
- partners.view and all-products workspace scope. Writes additionally require partners.manage. Relationship and product ownership checks still apply. The current generated-pool model requires productId/product_id and a regular price or price_cents estimate, including explicit 0 for a free product. quantity defaults to 1. Only generated_serials is supported; serial imports are rejected by this path. Product serial support and an active relationship are checked. The optional four-character prefix is letters/numbers. Expiry must be future-dated; automatic unused-serial removal requires an expiry. Supported snake-case aliases are accepted. This allocates inventory, not proof of a reported sale or payment. No blanket idempotency guarantee; reconcile an uncertain allocation before retrying.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"productId": {
"type": "integer",
"minimum": 1
},
"product_id": {
"type": "integer",
"minimum": 1
},
"relationshipProductId": {
"type": "integer",
"minimum": 1
},
"quantity": {
"type": "integer",
"minimum": 1
},
"batchLabel": {
"type": "string"
},
"notes": {
"type": "string"
},
"fulfillmentMode": {
"const": "generated_serials"
},
"prefix": {
"type": "string",
"pattern": "^[A-Za-z0-9]{4}$"
},
"price": {
"type": "number"
},
"price_cents": {
"type": "integer"
},
"sale_price": {
"type": "number"
},
"sale_price_cents": {
"type": "integer"
},
"expiresAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"autoRevokeUnusedOnExpiry": {
"type": "boolean"
},
"promoStart": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"promoExpires": {
"type": [
"string",
"null"
],
"format": "date-time"
}
},
"additionalProperties": true
}
HTTP 201 response (application/json)
{
"type": "object",
"properties": {
"pool": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
},
"allocation": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
},
"quantity": {
"type": "integer"
},
"count": {
"type": "integer"
},
"items_created": {
"type": "integer"
},
"serials": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/serials/{poolId}/export
Download allocated serials as private CSV
- Auth
- Account Bearer JWT
- Scope
- partners.view + partners.manage and all-products workspace scope.
- Returns
- HTTP 200: text/csv.
- Notes
- partners.view and all-products workspace scope. Relationship and product ownership checks still apply. The CSV contains one serial license per line, with no header, quotation marks, extra columns or byte-order mark. This read additionally requires partners.manage because the CSV contains usable serials. Preserve the private attachment; never expose it in public logs or documentation.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (text/csv)
{
"type": "string",
"format": "binary"
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/conversations
Read relationship conversation threads
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope.
- Returns
- HTTP 200: conversations.
- Notes
- partners.view and all-products workspace scope. Relationship and product ownership checks still apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"conversations": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/conversations
Start a relationship conversation
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope. Writes additionally require partners.manage.
- Request fields
- body: string
- message: string
- attachments: array
- internal_note: boolean
- subject: string (required)
- threadType: string
- linkedProductId: integer
- linkedExternalOrderId: integer
- Returns
- HTTP 201: thread, message.
- Notes
- partners.view and all-products workspace scope. Writes additionally require partners.manage. Relationship and product ownership checks still apply. A subject and non-empty body/message are required. Do not put customer credentials or full serials into messages.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"body": {
"type": "string"
},
"message": {
"type": "string"
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"internal_note": {
"type": "boolean"
},
"subject": {
"type": "string"
},
"threadType": {
"type": "string"
},
"linkedProductId": {
"type": "integer",
"minimum": 1
},
"linkedExternalOrderId": {
"type": "integer",
"minimum": 1
}
},
"required": [
"subject"
],
"additionalProperties": true,
"anyOf": [
{
"required": [
"body"
]
},
{
"required": [
"message"
]
}
]
}
HTTP 201 response (application/json)
{
"type": "object",
"properties": {
"thread": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
},
"message": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers/{relationshipId}/conversations/{threadId}/messages
Read messages in an owned relationship thread
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope.
- Request fields
- query limit: integer
- query offset: integer
- Returns
- HTTP 200: thread, messages, has_more, limit, offset.
- Notes
- partners.view and all-products workspace scope. Relationship and product ownership checks still apply. The thread must belong to this relationship. Message pages are returned in chronological display order.
Request, response and error reference
Query and header parameters
[
{
"name": "limit",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1
},
"required": false,
"description": ""
},
{
"name": "offset",
"in": "query",
"schema": {
"type": "integer"
},
"required": false,
"description": ""
}
]
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"thread": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
},
"messages": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"has_more": {
"type": "boolean"
},
"limit": {
"type": "integer"
},
"offset": {
"type": "integer"
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers/{relationshipId}/conversations/{threadId}/messages
Reply to an owned relationship thread
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope. Writes additionally require partners.manage.
- Request fields
- body: string
- message: string
- attachments: array
- internal_note: boolean
- Returns
- HTTP 201: message.
- Notes
- partners.view and all-products workspace scope. Writes additionally require partners.manage. Relationship and product ownership checks still apply.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"body": {
"type": "string"
},
"message": {
"type": "string"
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"internal_note": {
"type": "boolean"
}
},
"additionalProperties": true,
"anyOf": [
{
"required": [
"body"
]
},
{
"required": [
"message"
]
}
]
}
HTTP 201 response (application/json)
{
"type": "object",
"properties": {
"message": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/activity
Read the relationship activity history
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope.
- Request fields
- query limit: integer
- query offset: integer
- Returns
- HTTP 200: activity.
- Notes
- partners.view and all-products workspace scope. Relationship and product ownership checks still apply.
Request, response and error reference
Query and header parameters
[
{
"name": "limit",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1
},
"required": false,
"description": ""
},
{
"name": "offset",
"in": "query",
"schema": {
"type": "integer"
},
"required": false,
"description": ""
}
]
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"activity": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/overview
Read the current-month Partner Hub summary
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: overview.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. Reported reseller amounts and estimates are not funded SoundSync-managed checkout balances.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"overview": {
"type": "object",
"properties": {
"active_resellers": {
"type": "integer"
},
"pending_relationships": {
"type": "integer"
},
"external_reported_sales_cents": {
"type": "integer"
},
"external_order_count": {
"type": "integer"
},
"licenses_issued": {
"type": "integer"
},
"expected_payable_cents": {
"type": "integer"
},
"external_fulfillment_events": {
"type": "integer"
},
"api_health_warnings": {
"type": "integer"
},
"unread_partner_messages": {
"type": "integer"
}
},
"additionalProperties": true
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/sales-analytics
Read current-month reseller reporting by currency
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: period, currencies.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"period": {
"const": "current_month"
},
"currencies": {
"type": "array",
"items": {
"type": "object",
"properties": {
"currency": {
"type": "string"
},
"order_count": {
"type": "integer"
},
"gross_product_cents": {
"type": "number"
},
"refunded_line_cents": {
"type": "number"
},
"net_product_cents": {
"type": "number"
},
"developer_receivable_cents": {
"type": "number"
},
"reseller_remainder_cents": {
"type": "number"
}
},
"additionalProperties": true
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/hub-records/{kind}
Read the paginated workspace Partner Hub records
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Request fields
- query limit: integer
- query offset: integer
- Returns
- HTTP 200: kind, total, limit, offset, records.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. kind is orders, licenses, conversations, campaigns or statements. Default limit 25, maximum 100; offset is bounded to 1,000,000. Results can contain customer identity and serials and must remain private.
Request, response and error reference
Query and header parameters
[
{
"name": "limit",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100
},
"required": false,
"description": ""
},
{
"name": "offset",
"in": "query",
"schema": {
"type": "integer",
"minimum": 0
},
"required": false,
"description": ""
}
]
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"kind": {
"type": "string"
},
"total": {
"type": "integer"
},
"limit": {
"type": "integer"
},
"offset": {
"type": "integer"
},
"records": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/pool-estimates
Read serial-pool estimates grouped by currency
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: estimates, pool_count.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. Estimated reseller proceeds are not a customer payment, funded settlement or completed payout.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"estimates": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"pool_count": {
"type": "integer"
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/serial-pools
Read serial pools across owned relationships
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: pools.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"pools": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/overview
Read a relationship and its related records
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: relationship, products, orders, licenses, api_keys, conversations, statements, activity.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. Contains private historical records. URL alias: /resellers/{relationshipId}/overview.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"relationship": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
},
"products": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"orders": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"licenses": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"api_keys": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"conversations": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"statements": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"activity": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/orders
Read historical external orders
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Request fields
- query limit: integer
- query offset: integer
- Returns
- HTTP 200: orders, has_more, limit, offset.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. Default limit 25. The /resellers/{relationshipId}/orders GET alias is supported; its POST write remains retired.
Request, response and error reference
Query and header parameters
[
{
"name": "limit",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100
},
"required": false,
"description": ""
},
{
"name": "offset",
"in": "query",
"schema": {
"type": "integer",
"minimum": 0
},
"required": false,
"description": ""
}
]
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"orders": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"has_more": {
"type": "boolean"
},
"limit": {
"type": "integer"
},
"offset": {
"type": "integer"
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/customers
Read relationship customer purchase summaries
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: customers.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. At most 100 customer summaries. Includes private customer identity; no platform-wide customer-list access is granted. /resellers/{relationshipId}/customers is an alias.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"customers": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers/{relationshipId}/licenses
Read paginated relationship licenses
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Request fields
- query limit: integer
- query offset: integer
- Returns
- HTTP 200: licenses, has_more, limit, offset.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. Default limit 100; can include usable serials and customer identity. Preserve exact bigint IDs, which may arrive as decimal strings.
Request, response and error reference
Query and header parameters
[
{
"name": "limit",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100
},
"required": false,
"description": ""
},
{
"name": "offset",
"in": "query",
"schema": {
"type": "integer",
"minimum": 0
},
"required": false,
"description": ""
}
]
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"licenses": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"has_more": {
"type": "boolean"
},
"limit": {
"type": "integer"
},
"offset": {
"type": "integer"
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/financials
Read reported statement totals and historical statements
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: financials, statements.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. Read-only external-sale reporting, not SoundSync payout execution. /resellers/{relationshipId}/financials is an alias.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"financials": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
},
"statements": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/statements
Read historical reseller statements
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: statements.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"statements": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/api-health
Read key configuration and recent API request statistics
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: api_health.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. Status is a configuration heuristic based on enabled API and active keys; request counts use 30 days. It is not a real-time connection or delivery guarantee.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"api_health": {
"type": "object",
"properties": {
"status": {
"type": "string"
},
"request_count": {
"type": "integer"
},
"error_count": {
"type": "integer"
},
"error_rate": {
"type": "number"
},
"last_sync_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"active_key_count": {
"type": "integer"
}
},
"additionalProperties": true
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/{relationshipId}/settings
Read the saved relationship settings
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: settings.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"settings": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers/{relationshipId}/terms
Save relationship commercial and visibility terms
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Request fields
- displayName: string
- display_name: string,null
- currency: string
- default_currency: string
- commercialModel: string
- default_wholesale_rate_cents: integer
- wholesale_rate: number
- commissionRateBps: integer
- developerRevenueShareBps: integer
- paymentTerms: string
- refundPolicy: string
- customerVisibilityMode: string
- apiEnabled: boolean
- manualIssueEnabled: boolean
- staticSerialExportEnabled: boolean
- monthlyLicenseCap: integer,null
- statementCycle: string
- termStatus: string
- Returns
- HTTP 200: relationship.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. Supported snake-case aliases include commercial_model, default_commission_rate_bps, default_developer_revenue_share_bps, payment_terms, default_refund_policy, customer_visibility_mode, api_enabled, manual_issue_enabled, static_serial_export_enabled and monthly_license_cap. Share rates are basis points. PATCH /{relationshipId}/settings and /resellers/{relationshipId}/settings are aliases. Changes are real commercial settings, not a preview; they do not enable a platform financial flag or prove a payment.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"displayName": {
"type": "string"
},
"display_name": {
"type": [
"string",
"null"
]
},
"currency": {
"type": "string"
},
"default_currency": {
"type": "string"
},
"commercialModel": {
"type": "string"
},
"default_wholesale_rate_cents": {
"type": "integer"
},
"wholesale_rate": {
"type": "number"
},
"commissionRateBps": {
"type": "integer"
},
"developerRevenueShareBps": {
"type": "integer"
},
"paymentTerms": {
"type": "string"
},
"refundPolicy": {
"type": "string"
},
"customerVisibilityMode": {
"type": "string"
},
"apiEnabled": {
"type": "boolean"
},
"manualIssueEnabled": {
"type": "boolean"
},
"staticSerialExportEnabled": {
"type": "boolean"
},
"monthlyLicenseCap": {
"type": [
"integer",
"null"
]
},
"statementCycle": {
"type": "string"
},
"termStatus": {
"type": "string"
}
},
"additionalProperties": true
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"relationship": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers/{relationshipId}/suspend
Suspend the supported relationship
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: relationship.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. Changes relationship state. It does not refund external payments or erase historical orders and required accounting.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"relationship": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers/{relationshipId}/end
End the supported relationship
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: relationship.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. Changes relationship state. It does not refund external payments or erase historical orders and required accounting.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"relationship": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers/{relationshipId}/campaigns
Read relationship scheduled deals
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: campaigns.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"campaigns": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers/{relationshipId}/campaigns
Create a reseller scheduled deal
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Request fields
- name: string (required)
- description: string
- status: draft | requested | approved | active | paused | ended | settled | disputed | cancelled
- startAt: string,null
- endAt: string,null
- currency: string
- notes: string
- relationshipProductId: integer
- productId: integer
- approved_sale_price_cents: integer
- commercialModel: string
- wholesale_rate_cents: integer
- commissionRateBps: integer
- developerRevenueShareBps: integer
- licenseCap: integer,null
- Returns
- HTTP 201: campaign.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. A name is required on both create and edit. This is not a sparse PATCH: omitted status becomes draft and omitted descriptions, dates and notes are cleared. Supported snake-case aliases apply. Optional productId/relationshipProductId must resolve to an approved assignment. A partner deal is not a marketing email, managed-checkout promo code or completed sale.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"draft",
"requested",
"approved",
"active",
"paused",
"ended",
"settled",
"disputed",
"cancelled"
]
},
"startAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"endAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"currency": {
"type": "string"
},
"notes": {
"type": "string"
},
"relationshipProductId": {
"type": "integer",
"minimum": 1
},
"productId": {
"type": "integer",
"minimum": 1
},
"approved_sale_price_cents": {
"type": "integer"
},
"commercialModel": {
"type": "string"
},
"wholesale_rate_cents": {
"type": "integer"
},
"commissionRateBps": {
"type": "integer"
},
"developerRevenueShareBps": {
"type": "integer"
},
"licenseCap": {
"type": [
"integer",
"null"
]
}
},
"required": [
"name"
],
"additionalProperties": true
}
HTTP 201 response (application/json)
{
"type": "object",
"properties": {
"campaign": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers/{relationshipId}/campaigns/{campaignId}
Replace reseller scheduled-deal details
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Request fields
- name: string (required)
- description: string
- status: draft | requested | approved | active | paused | ended | settled | disputed | cancelled
- startAt: string,null
- endAt: string,null
- currency: string
- notes: string
- relationshipProductId: integer
- productId: integer
- approved_sale_price_cents: integer
- commercialModel: string
- wholesale_rate_cents: integer
- commissionRateBps: integer
- developerRevenueShareBps: integer
- licenseCap: integer,null
- Returns
- HTTP 200: campaign.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. A name is required on both create and edit. This is not a sparse PATCH: omitted status becomes draft and omitted descriptions, dates and notes are cleared. Supported snake-case aliases apply. Optional productId/relationshipProductId must resolve to an approved assignment. A partner deal is not a marketing email, managed-checkout promo code or completed sale.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"draft",
"requested",
"approved",
"active",
"paused",
"ended",
"settled",
"disputed",
"cancelled"
]
},
"startAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"endAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"currency": {
"type": "string"
},
"notes": {
"type": "string"
},
"relationshipProductId": {
"type": "integer",
"minimum": 1
},
"productId": {
"type": "integer",
"minimum": 1
},
"approved_sale_price_cents": {
"type": "integer"
},
"commercialModel": {
"type": "string"
},
"wholesale_rate_cents": {
"type": "integer"
},
"commissionRateBps": {
"type": "integer"
},
"developerRevenueShareBps": {
"type": "integer"
},
"licenseCap": {
"type": [
"integer",
"null"
]
}
},
"required": [
"name"
],
"additionalProperties": true
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"campaign": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/partners/resellers/{relationshipId}/api-keys
Read key metadata without revealing private key material
- Auth
- Account Bearer JWT
- Scope
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply.
- Returns
- HTTP 200: api_keys.
- Notes
- partners.view and all-products workspace scope; writes additionally require partners.manage. Owned relationship checks apply. Historical GET access is separate from retired key creation/rotation/revocation writes in this developer router.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"api_keys": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/products/{productId}/promo-kit
Read product partner copy and media
- Auth
- Account Bearer JWT
- Scope
- partners.manage and assigned-product access, including GET. The product must belong to the effective developer; all-products scope is not required for an assigned product.
- Returns
- HTTP 200: promo_kit.
- Notes
- partners.manage and assigned-product access, including GET. The product must belong to the effective developer; all-products scope is not required for an assigned product.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"promo_kit": {
"type": [
"object",
"null"
],
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/products/{productId}/promo-kit
Replace product partner copy and commercial presentation
- Auth
- Account Bearer JWT
- Scope
- partners.manage and assigned-product access, including GET. The product must belong to the effective developer; all-products scope is not required for an assigned product.
- Request fields
- title: string
- shortDescription: string
- longDescription: string
- featureBullets: array
- category: string
- tags: array
- msrp_cents: integer
- suggested_sale_price_cents: integer
- currency: string
- approvedDiscountRules: string
- systemRequirements: string
- licenseTerms: string
- emailCopy: string
- socialCopy: string
- adCopy: string
- brandGuidelines: string
- status: string
- Returns
- HTTP 200: promo_kit.
- Notes
- partners.manage and assigned-product access, including GET. The product must belong to the effective developer; all-products scope is not required for an assigned product. Read the kit first. Omitted descriptive fields, lists and price suggestions reset to defaults/null; this is a replacement. Supported snake-case field names and msrp/suggested_sale_price decimal aliases are accepted. Saves suggestions and approved copy, not product pricing or an active sale.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"title": {
"type": "string"
},
"shortDescription": {
"type": "string"
},
"longDescription": {
"type": "string"
},
"featureBullets": {
"type": "array",
"items": {
"type": "string"
}
},
"category": {
"type": "string"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"msrp_cents": {
"type": "integer"
},
"suggested_sale_price_cents": {
"type": "integer"
},
"currency": {
"type": "string"
},
"approvedDiscountRules": {
"type": "string"
},
"systemRequirements": {
"type": "string"
},
"licenseTerms": {
"type": "string"
},
"emailCopy": {
"type": "string"
},
"socialCopy": {
"type": "string"
},
"adCopy": {
"type": "string"
},
"brandGuidelines": {
"type": "string"
},
"status": {
"type": "string"
}
},
"additionalProperties": true
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"promo_kit": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/products/{productId}/promo-kit/assets
Attach an authorized promotional media reference
- Auth
- Account Bearer JWT
- Scope
- partners.manage and assigned-product access, including GET. The product must belong to the effective developer; all-products scope is not required for an assigned product.
- Request fields
- assetType: image | logo | screenshot | audio_demo | video | document | banner | other
- title: string
- description: string
- url: string
- storageKey: string
- mimeType: string
- sortOrder: integer
- Returns
- HTTP 201: asset.
- Notes
- partners.manage and assigned-product access, including GET. The product must belong to the effective developer; all-products scope is not required for an assigned product. Accepts asset_type/storage_key/mime_type/sort_order aliases. Requires a URL or storage key, not a binary file upload. Can initialize a missing promo kit.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"assetType": {
"type": "string",
"enum": [
"image",
"logo",
"screenshot",
"audio_demo",
"video",
"document",
"banner",
"other"
]
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"url": {
"type": "string"
},
"storageKey": {
"type": "string"
},
"mimeType": {
"type": "string"
},
"sortOrder": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": true,
"anyOf": [
{
"required": [
"url"
]
},
{
"required": [
"storageKey"
]
},
{
"required": [
"storage_key"
]
}
]
}
HTTP 201 response (application/json)
{
"type": "object",
"properties": {
"asset": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/products/{productId}/promo-kit/assets/{assetId}
Edit a product promotional asset reference
- Auth
- Account Bearer JWT
- Scope
- partners.manage and assigned-product access, including GET. The product must belong to the effective developer; all-products scope is not required for an assigned product.
- Request fields
- assetType: image | logo | screenshot | audio_demo | video | document | banner | other
- title: string
- description: string
- url: string
- storageKey: string
- mimeType: string
- sortOrder: integer
- Returns
- HTTP 200: asset.
- Notes
- partners.manage and assigned-product access, including GET. The product must belong to the effective developer; all-products scope is not required for an assigned product. Omitted asset fields retain saved values; the URL or storage key must still resolve in the normalized reference. Does not change marketplace artwork approval.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"assetType": {
"type": "string",
"enum": [
"image",
"logo",
"screenshot",
"audio_demo",
"video",
"document",
"banner",
"other"
]
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"url": {
"type": "string"
},
"storageKey": {
"type": "string"
},
"mimeType": {
"type": "string"
},
"sortOrder": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": true
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"asset": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/products/{productId}/promo-kit/assets/{assetId}
Remove an owned promotional asset reference
- Auth
- Account Bearer JWT
- Scope
- partners.manage and assigned-product access, including GET. The product must belong to the effective developer; all-products scope is not required for an assigned product.
- Returns
- HTTP 200: deleted, asset.
- Notes
- partners.manage and assigned-product access, including GET. The product must belong to the effective developer; all-products scope is not required for an assigned product. Deletes the reference row; does not promise deletion of the underlying stored file or erase customer purchases.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"deleted": {
"type": "boolean"
},
"asset": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
