Solo invoices
Solo invoice request and response fields.
Base URL https://api.klockwork.org. Send the agency key and X-Klockwork-Talent (or talentId). The call acts as that active talent. /api/public/solo/public returns 404.
List invoices
GET /api/public/solo/invoices
Response 200: { invoices: Invoice[] }
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
clerkUserId | string, min 1 | yes |
clientId | string (uuid) | yes |
invoicePrefix | string, min 1 | yes |
invoiceNumber | integer | yes |
fromAt | string | yes |
toAt | string | yes |
currency | string, min 1, max 8 | yes |
status | "draft" or "sent" or "viewed" or "void" or "paid" or "overdue" | yes |
paymentTerms | string or null | yes |
taxMode | "none" or "vat_12" or "custom" | yes |
customTaxLabel | string or null | yes |
customTaxRateBps | integer, min 0 or null | yes |
notes | string or null | yes |
businessSnapshot | object | yes |
payoutSnapshot | object | yes |
subtotalCents | integer, min 0 | yes |
taxCents | integer, min 0 | yes |
totalCents | integer, min 0 | yes |
issuedAt | string or null | yes |
dueAt | string or null | yes |
paidAt | string or null | yes |
createdAt | string | yes |
updatedAt | string | yes |
lineItems | array of object | yes |
lineItems items:
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
invoiceId | string (uuid) | yes |
sessionId | string (uuid) or null | yes |
description | string | yes |
quantityHours | number, min 0 | yes |
unitRateCents | integer, min 0 | yes |
amountCents | integer, min 0 | yes |
sortOrder | integer, min -9007199254740991 | yes |
createdAt | string | yes |
Create an invoice
POST /api/public/solo/invoices
Request body:
| Field | Type | Required |
|---|---|---|
clientId | string (uuid) | yes |
from | string, min 1 | yes |
to | string, min 1 | yes |
notes | string, max 4000 | no |
Response 201: { invoice: Invoice }
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
clerkUserId | string, min 1 | yes |
clientId | string (uuid) | yes |
invoicePrefix | string, min 1 | yes |
invoiceNumber | integer | yes |
fromAt | string | yes |
toAt | string | yes |
currency | string, min 1, max 8 | yes |
status | "draft" or "sent" or "viewed" or "void" or "paid" or "overdue" | yes |
paymentTerms | string or null | yes |
taxMode | "none" or "vat_12" or "custom" | yes |
customTaxLabel | string or null | yes |
customTaxRateBps | integer, min 0 or null | yes |
notes | string or null | yes |
businessSnapshot | object | yes |
payoutSnapshot | object | yes |
subtotalCents | integer, min 0 | yes |
taxCents | integer, min 0 | yes |
totalCents | integer, min 0 | yes |
issuedAt | string or null | yes |
dueAt | string or null | yes |
paidAt | string or null | yes |
createdAt | string | yes |
updatedAt | string | yes |
lineItems | array of object | yes |
lineItems items:
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
invoiceId | string (uuid) | yes |
sessionId | string (uuid) or null | yes |
description | string | yes |
quantityHours | number, min 0 | yes |
unitRateCents | integer, min 0 | yes |
amountCents | integer, min 0 | yes |
sortOrder | integer, min -9007199254740991 | yes |
createdAt | string | yes |
Get an invoice
GET /api/public/solo/invoices/{id}
Response 200: { invoice: Invoice }
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
clerkUserId | string, min 1 | yes |
clientId | string (uuid) | yes |
invoicePrefix | string, min 1 | yes |
invoiceNumber | integer | yes |
fromAt | string | yes |
toAt | string | yes |
currency | string, min 1, max 8 | yes |
status | "draft" or "sent" or "viewed" or "void" or "paid" or "overdue" | yes |
paymentTerms | string or null | yes |
taxMode | "none" or "vat_12" or "custom" | yes |
customTaxLabel | string or null | yes |
customTaxRateBps | integer, min 0 or null | yes |
notes | string or null | yes |
businessSnapshot | object | yes |
payoutSnapshot | object | yes |
subtotalCents | integer, min 0 | yes |
taxCents | integer, min 0 | yes |
totalCents | integer, min 0 | yes |
issuedAt | string or null | yes |
dueAt | string or null | yes |
paidAt | string or null | yes |
createdAt | string | yes |
updatedAt | string | yes |
lineItems | array of object | yes |
lineItems items:
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
invoiceId | string (uuid) | yes |
sessionId | string (uuid) or null | yes |
description | string | yes |
quantityHours | number, min 0 | yes |
unitRateCents | integer, min 0 | yes |
amountCents | integer, min 0 | yes |
sortOrder | integer, min -9007199254740991 | yes |
createdAt | string | yes |
Update an invoice
PATCH /api/public/solo/invoices/{id}
Request body:
| Field | Type | Required |
|---|---|---|
notes | string, max 4000 | no |
dueAt | string or null | no |
paymentTerms | string, max 80 or null | no |
lineItemDescriptions | array of object | no |
reason | string, max 1000 | no |
markSent | boolean | no |
lineItemDescriptions items:
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
description | string, min 1, max 500 | yes |
Response 200: { invoice: Invoice }
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
clerkUserId | string, min 1 | yes |
clientId | string (uuid) | yes |
invoicePrefix | string, min 1 | yes |
invoiceNumber | integer | yes |
fromAt | string | yes |
toAt | string | yes |
currency | string, min 1, max 8 | yes |
status | "draft" or "sent" or "viewed" or "void" or "paid" or "overdue" | yes |
paymentTerms | string or null | yes |
taxMode | "none" or "vat_12" or "custom" | yes |
customTaxLabel | string or null | yes |
customTaxRateBps | integer, min 0 or null | yes |
notes | string or null | yes |
businessSnapshot | object | yes |
payoutSnapshot | object | yes |
subtotalCents | integer, min 0 | yes |
taxCents | integer, min 0 | yes |
totalCents | integer, min 0 | yes |
issuedAt | string or null | yes |
dueAt | string or null | yes |
paidAt | string or null | yes |
createdAt | string | yes |
updatedAt | string | yes |
lineItems | array of object | yes |
lineItems items:
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
invoiceId | string (uuid) | yes |
sessionId | string (uuid) or null | yes |
description | string | yes |
quantityHours | number, min 0 | yes |
unitRateCents | integer, min 0 | yes |
amountCents | integer, min 0 | yes |
sortOrder | integer, min -9007199254740991 | yes |
createdAt | string | yes |
Void an invoice
POST /api/public/solo/invoices/{id}/void
The body may be {}.
No request body.
Response 200: { invoice: Invoice }
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
clerkUserId | string, min 1 | yes |
clientId | string (uuid) | yes |
invoicePrefix | string, min 1 | yes |
invoiceNumber | integer | yes |
fromAt | string | yes |
toAt | string | yes |
currency | string, min 1, max 8 | yes |
status | "draft" or "sent" or "viewed" or "void" or "paid" or "overdue" | yes |
paymentTerms | string or null | yes |
taxMode | "none" or "vat_12" or "custom" | yes |
customTaxLabel | string or null | yes |
customTaxRateBps | integer, min 0 or null | yes |
notes | string or null | yes |
businessSnapshot | object | yes |
payoutSnapshot | object | yes |
subtotalCents | integer, min 0 | yes |
taxCents | integer, min 0 | yes |
totalCents | integer, min 0 | yes |
issuedAt | string or null | yes |
dueAt | string or null | yes |
paidAt | string or null | yes |
createdAt | string | yes |
updatedAt | string | yes |
lineItems | array of object | yes |
lineItems items:
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
invoiceId | string (uuid) | yes |
sessionId | string (uuid) or null | yes |
description | string | yes |
quantityHours | number, min 0 | yes |
unitRateCents | integer, min 0 | yes |
amountCents | integer, min 0 | yes |
sortOrder | integer, min -9007199254740991 | yes |
createdAt | string | yes |
List invoice events
GET /api/public/solo/invoices/{id}/events
Response 200: { events: Event[] }
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
clerkUserId | string, min 1 | yes |
invoiceId | string (uuid) | yes |
action | "created" or "updated" or "voided" or "status_changed" | yes |
actorLabel | string | yes |
reason | string or null | yes |
before | object or null | yes |
after | object or null | yes |
createdAt | string | yes |
List invoice shares
GET /api/public/solo/invoices/{id}/shares
Response 200: { shares: Share[] }
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
clerkUserId | string, min 1 | yes |
invoiceId | string (uuid) | yes |
token | string, min 1 | yes |
createdAt | string | yes |
revokedAt | string or null | yes |
expiresAt | string or null | yes |
status | "active" or "revoked" or "expired" | yes |
viewCount | integer, min 0 | yes |
lastViewedAt | string or null | yes |
totalViewDurationMs | integer, min 0 | yes |
views | array of object | yes |
views items:
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
shareId | string (uuid) | yes |
startedAt | string | yes |
lastSeenAt | string | yes |
endedAt | string or null | yes |
durationMs | integer, min 0 | yes |
createdAt | string | yes |
Create an invoice share
POST /api/public/solo/invoices/{id}/shares
The body may be {} when every share field is optional.
Request body:
| Field | Type | Required |
|---|---|---|
expiresInDays | integer, max 365, default 30 | no |
Response 201: { share: Share }
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
clerkUserId | string, min 1 | yes |
invoiceId | string (uuid) | yes |
token | string, min 1 | yes |
createdAt | string | yes |
revokedAt | string or null | yes |
expiresAt | string or null | yes |
status | "active" or "revoked" or "expired" | yes |
viewCount | integer, min 0 | yes |
lastViewedAt | string or null | yes |
totalViewDurationMs | integer, min 0 | yes |
views | array of object | yes |
views items:
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
shareId | string (uuid) | yes |
startedAt | string | yes |
lastSeenAt | string | yes |
endedAt | string or null | yes |
durationMs | integer, min 0 | yes |
createdAt | string | yes |
Revoke an invoice share
POST /api/public/solo/invoices/shares/{id}/revoke
No request body.
Response 200: { share: Share }
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
clerkUserId | string, min 1 | yes |
invoiceId | string (uuid) | yes |
token | string, min 1 | yes |
createdAt | string | yes |
revokedAt | string or null | yes |
expiresAt | string or null | yes |
status | "active" or "revoked" or "expired" | yes |
viewCount | integer, min 0 | yes |
lastViewedAt | string or null | yes |
totalViewDurationMs | integer, min 0 | yes |
views | array of object | yes |
views items:
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
shareId | string (uuid) | yes |
startedAt | string | yes |
lastSeenAt | string | yes |
endedAt | string or null | yes |
durationMs | integer, min 0 | yes |
createdAt | string | yes |
List unbilled time
GET /api/public/solo/invoices/unbilled
Response 200: { summary: Summary }
| Field | Type | Required |
|---|---|---|
clients | array of object | yes |
sessionCount | integer, min 0 | yes |
totalBillableMs | number, min 0 | yes |
currency | string, min 1, max 8 or null | yes |
totalCents | integer, min 0 or null | yes |
clients items:
| Field | Type | Required |
|---|---|---|
clientId | string (uuid) | yes |
clientName | string | yes |
currency | string, min 1, max 8 | yes |
amountCents | integer, min 0 | yes |
billableMs | number, min 0 | yes |
sessionCount | integer, min 0 | yes |
List timesheet shares
GET /api/public/solo/timesheet/shares
Query:
| Field | Type | Required |
|---|---|---|
clientId | string (uuid) | no |
Response 200: { shares: Share[] }
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
clerkUserId | string, min 1 | yes |
clientId | string (uuid) | yes |
fromAt | string | yes |
toAt | string | yes |
token | string, min 1 | yes |
createdAt | string | yes |
revokedAt | string or null | yes |
expiresAt | string or null | yes |
status | "active" or "revoked" or "expired" | yes |
viewCount | integer, min 0 | yes |
lastViewedAt | string or null | yes |
totalViewDurationMs | integer, min 0 | yes |
views | array of object | yes |
views items:
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
shareId | string (uuid) | yes |
startedAt | string | yes |
lastSeenAt | string | yes |
endedAt | string or null | yes |
durationMs | integer, min 0 | yes |
createdAt | string | yes |
Create a timesheet share
POST /api/public/solo/timesheet/shares
Request body:
| Field | Type | Required |
|---|---|---|
clientId | string (uuid) | yes |
from | string, min 1 | yes |
to | string, min 1 | yes |
expiresInDays | integer, max 365, default 30 | no |
Response 201: { share: Share }
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
clerkUserId | string, min 1 | yes |
clientId | string (uuid) | yes |
fromAt | string | yes |
toAt | string | yes |
token | string, min 1 | yes |
createdAt | string | yes |
revokedAt | string or null | yes |
expiresAt | string or null | yes |
status | "active" or "revoked" or "expired" | yes |
viewCount | integer, min 0 | yes |
lastViewedAt | string or null | yes |
totalViewDurationMs | integer, min 0 | yes |
views | array of object | yes |
views items:
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
shareId | string (uuid) | yes |
startedAt | string | yes |
lastSeenAt | string | yes |
endedAt | string or null | yes |
durationMs | integer, min 0 | yes |
createdAt | string | yes |
Revoke a timesheet share
POST /api/public/solo/timesheet/shares/{id}/revoke
No request body.
Response 200: { share: Share }
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
clerkUserId | string, min 1 | yes |
clientId | string (uuid) | yes |
fromAt | string | yes |
toAt | string | yes |
token | string, min 1 | yes |
createdAt | string | yes |
revokedAt | string or null | yes |
expiresAt | string or null | yes |
status | "active" or "revoked" or "expired" | yes |
viewCount | integer, min 0 | yes |
lastViewedAt | string or null | yes |
totalViewDurationMs | integer, min 0 | yes |
views | array of object | yes |
views items:
| Field | Type | Required |
|---|---|---|
id | string (uuid) | yes |
shareId | string (uuid) | yes |
startedAt | string | yes |
lastSeenAt | string | yes |
endedAt | string or null | yes |
durationMs | integer, min 0 | yes |
createdAt | string | yes |
