API reference
List milestones
/ api/ v1/ milestonesContractor milestones, newest first, with the row id breaking equal timestamps: how each was verified, and whether it was paid. Only a real 0x transaction is exposed as txHash.
Send a workspace API key as Authorization: Bearer ….
Parameters
limitintegeroptionalHow many items to return. Defaults to 50; a larger value is capped at 200.
Default:
50Allowed:1 to 200
cursorstringoptionalThe previous response's
page.nextCursor, passed back unchanged to continue. Opaque: never decode or construct one. A cursor this endpoint could not have issued is refused with400.statusstringoptionalOnly milestones in this status.
Allowed:
pendingverifiedpaidheldclosedcontractorIdstringoptionalOnly milestones for this contractor.
Try it
The key is kept in memory only, for this page.
Code samples
curl "https://www.vestiarion.xyz/api/v1/milestones" \
-H "Authorization: Bearer $VESTIARION_API_KEY"Response
Example{
"data": [
{
"id": "d01b2b49-2ca3-45fe-898c-f2c0128f6188",
"title": "Landing page redesign — milestone 2",
"amount": 0.9,
"status": "paid",
"verificationSource": "timesheet:kimai",
"verificationMethod": "seed",
"verificationStatus": "verified",
"verificationCheckedAt": null,
"verifiedAt": "2026-09-24T11:54:57.14+00:00",
"verificationDetail": {
"fixture": true
},
"verified": true,
"decidedAt": "2026-09-24T11:55:54.276+00:00",
"settledAt": "2026-09-24T11:55:54.276+00:00",
"closedAt": null,
"closeReason": null,
"agentReasoning": "Milestone 'Landing page redesign — milestone 2' for 0.9 USDC is verified via timesheet:kimai, contractor Diego Ramirez has riskLevel 'clear' (not high), and the amount 0.9 is below his paymentLimit of 2.5. No duplicate invoice or PO mismatch indicated, and verification source is confirmed, so immediate release is justified rather than deferring to Net-30.",
"txHash": "0xa710040ac59af4501a4c91f70287f1fecec1aad037e5d0fc2141fe270f81d969",
"contractor": {
"id": "5541f1a4-4e48-4fa5-880c-9ffc97d8953b",
"name": "Diego Ramirez — Design Contractor",
"riskLevel": "clear"
},
"createdAt": "2026-09-24T11:54:57.933771+00:00"
}
],
"page": {
"nextCursor": "eyJrIjoiMjAyNi0wOS0yNFQxMTo1NDo1Ny45MzM3NzErMDA6MDAiLCJpZCI6ImQwMWIyYjQ5LTJjYTMtNDVmZS04OThjLWYyYzAxMjhmNjE4OCJ9",
"hasMore": true,
"count": 1
}
}dataarray of object19 fields in data
idstringtitlestringamountnumberstatusstringOne of
pendingverifiedpaidheldclosedverificationSourcestring · nullableverificationMethodstringOne of
unverifiedgithubmanualseedverificationStatusstringOne of
unverifiedverifiednot_mergedunavailablefailedverificationCheckedAtstring · nullableverifiedAtstring · nullableverificationDetailobjectverifiedbooleandecidedAtstring · nullablesettledAtstring · nullableclosedAtstring · nullableWhen a person closed the milestone without paying it (status closed), else null.
closeReasonstring · nullableThe reason the person gave for closing it without paying, else null.
agentReasoningstring · nullabletxHashstring · nullableAn on-chain hash when the payment settled on Arc, else null.
contractorobject · nullable3 fields in contractor
idstringnamestringriskLevelstring
createdAtstring
pageobjectWhere this page sits in the collection.
3 fields in page
nextCursorstring · nullablePass back as
?cursor=to continue. Null when the end is reached.hasMorebooleanWhether another page follows this one.
countintegerHow many items this response carries.
Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid_request | An invalid limit or cursor, a filter value outside its allowed values, or a request body that does not validate. The message names the parameter or the field, and lists the accepted values. |
| 401 | unauthorized | No key, or a malformed, unknown or revoked one: "A valid API key is required." |
| 403 | forbidden | The key's scopes do not cover this route: "This key cannot do that." Or, on a write, the person who created the key can no longer add records: "This key's issuer can no longer add records in this workspace." |
| 500 | internal | An unexpected server error. Implementation details are not exposed. |