KlockworkKlockworkAPI
Agency

Partnership

Partnership administration with an agency key.

Base URL https://api.klockwork.org. Send X-Klockwork-Key or Authorization: Bearer kw_…. An agency key acts as the agency that created it. JSON bodies use these fields. A missing required field returns 400 with { "error": "Validation failed", "details": {} }.

These routes use the agency key of the partner company. Customer calls made with a partner key are under Partner.

Get the partnership

GET /api/public/agency/partner

A company that is not a partner returns 404 { "error": "This company is not a partner" }. A member who is not an admin returns 403 { "error": "Only a company admin can do this" }.

Response 200: { partner: Partner }

FieldTypeRequired
idstring (uuid)yes
clerkOrgIdstringyes
displayNamestringyes
contactEmailstring or nullyes
status"pending" or "active" or "suspended" or "terminated" or "rejected"yes
subscriptionExemptbooleanyes
monthlyRequestCapinteger, min -9007199254740991 or nullyes
acceptanceFeeCentsinteger, min -9007199254740991yes
acceptanceFeeStatus"due" or "paid" or "waived"yes
activatedAtstring or nullyes
suspendedAtstring or nullyes
terminatedAtstring or nullyes

Request a partnership

POST /api/public/agency/partner/request

The body may be {}. This request does not charge the company.

Request body:

FieldTypeRequired
contactEmailstring (email), max 200no

Response 201: { partner: Partner }

FieldTypeRequired
idstring (uuid)yes
clerkOrgIdstringyes
displayNamestringyes
contactEmailstring or nullyes
status"pending" or "active" or "suspended" or "terminated" or "rejected"yes
subscriptionExemptbooleanyes
monthlyRequestCapinteger, min -9007199254740991 or nullyes
acceptanceFeeCentsinteger, min -9007199254740991yes
acceptanceFeeStatus"due" or "paid" or "waived"yes
activatedAtstring or nullyes
suspendedAtstring or nullyes
terminatedAtstring or nullyes

List partner customers

GET /api/public/agency/partner/customers

Response 200: { customers: Customer[] }

Customer objects use the same fields as Customers.

Create a partner customer

POST /api/public/agency/partner/customers

Request body:

FieldTypeRequired
companyNamestring, min 1, max 160yes
invoiceEmailstring (email), max 200yes

Response 201: { customer, inviteUrl, invitationSent }

End, suspend, or restore a customer

POST /api/public/agency/partner/customers/{id}/end

The same empty body and { "ok": true } response apply to /suspend and /restore. An unknown id returns 404 { "error": "Customer not found" }.

No request body.

Response 200: { ok: true }

List partner keys

GET /api/public/agency/partner/keys

Response 200: { keys: PartnerKey[] }

FieldTypeRequired
idstring (uuid)yes
namestringyes
keyPrefixstringyes
environment"live" or "test"yes
scopesarray of "status:read" or "customers:read" or "customers:write"yes
expiresAtstring or nullyes
lastUsedAtstring or nullyes
revokedAtstring or nullyes
createdAtstringyes

Create a partner key

POST /api/public/agency/partner/keys

secret is returned once. A twentieth active key returns 409 { "error": "This company already has the maximum of 20 active API keys" }. A duplicate name returns 409 { "error": "An active API key with this name already exists" }.

Request body:

FieldTypeRequired
namestring, min 1, max 64yes
environment"live" or "test"yes
scopesarray of "status:read" or "customers:read" or "customers:write"yes

Response 201: { apiKey: PartnerKey, secret: string }

FieldTypeRequired
idstring (uuid)yes
namestringyes
keyPrefixstringyes
environment"live" or "test"yes
scopesarray of "status:read" or "customers:read" or "customers:write"yes
expiresAtstring or nullyes
lastUsedAtstring or nullyes
revokedAtstring or nullyes
createdAtstringyes

Revoke a partner key

POST /api/public/agency/partner/keys/{id}/revoke

No request body.

Response 200: { ok: true }

Get open terms

GET /api/public/agency/partner/terms

Response 200: { terms: Terms | null }

FieldTypeRequired
idstring (uuid)yes
model"wholesale_fixed" or "revenue_share" or "hybrid"yes
wholesaleCentsinteger, min -9007199254740991 or nullyes
revenueShareBpsinteger, min -9007199254740991 or nullyes
volumeTiersarray of object or nullyes
effectiveFromstringyes

volumeTiers items:

FieldTypeRequired
upTointeger or nullyes
wholesaleCentsinteger, min 0yes

Volume tier items:

FieldTypeRequired
upTointeger or nullyes
wholesaleCentsinteger, min 0yes

Get the monthly report

GET /api/public/agency/partner/report

Query periodStart is YYYY-MM-01. Omit it to use the current UTC month. Any other day returns 400 { "error": "periodStart must be the first day of a month" }.

Response 200: { report }

The report object:

FieldType
periodStartdate
periodEnddate
terms{ model, wholesaleCents, revenueShareBps, volumeTiers } or null
usage.requestCountnumber
usage.keyCountnumber
usage.busiestDatedate or null
usage.degradedboolean
reconciliation.customerCountnumber
reconciliation.billableCountnumber
reconciliation.openCountnumber
reconciliation.adjustedCountnumber
reconciliation.amountCentsnumber
reconciliation.wholesaleCentsnumber
reconciliation.shareCentsnumber
reconciliation.reportedCollectedCentsnumber
reconciliation.unreportedCountnumber
periodsarray of period rows

Each period row: id, customerClerkOrgId, billable, amountCents, wholesaleCents, shareCents, reportedCollectedCents, status.

On this page