Skip to content
SoundSyncAudio software platform

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 pathCurrent result
POST /api/developer/partners/{relationshipId}/orders410 PARTNER_FULFILLMENT_DISABLED; authorized historical GET reads remain separate.
POST /api/developer/partners/resellers/{relationshipId}/orders410 PARTNER_FULFILLMENT_DISABLED; not the external partner order API.
POST /api/developer/partners/resellers/{relationshipId}/api-keys and /api-keys/{keyId}/rotate or /revoke410 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

Partner API

Approved external partner requests and credentials.

WooCommerce

Connection, mapping, orders and serial reconciliation.

Recipient programs

Affiliates, collaborators, attribution and balances.

SoundSync

Requests and responses

GET /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.

GET /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.

GET /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.

POST /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.

POST /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.

POST /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.

POST /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.

POST /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.

GET /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.

POST /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.

PATCH /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.

DELETE /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.

GET /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.

POST /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.

GET /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.

GET /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.

POST /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.

GET /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.

POST /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.

GET /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.

GET /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.

GET /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.

GET /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.

GET /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.

GET /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.

GET /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.

GET /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.

GET /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.

GET /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.

GET /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.

GET /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.

GET /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.

GET /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.

PATCH /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.

POST /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.

POST /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.

GET /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.

POST /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.

PATCH /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.

GET /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.

GET /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.

PUT /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.

POST /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.

PATCH /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.

DELETE /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.