Skip to content
VestiarionDocs

API reference

List milestones

GET/api/v1/milestones

Contractor 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

  • limitintegeroptional

    How many items to return. Defaults to 50; a larger value is capped at 200.

    Default:50

    Allowed:1 to 200

  • cursorstringoptional

    The 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 with 400.

  • statusstringoptional

    Only milestones in this status.

    Allowed:pendingverifiedpaidheldclosed

  • contractorIdstringoptional

    Only milestones for this contractor.

Try it

The key is kept in memory only, for this page.

Code samples

cURL
curl "https://www.vestiarion.xyz/api/v1/milestones" \
  -H "Authorization: Bearer $VESTIARION_API_KEY"

Response

Example
200 · application/json
{
  "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
  }
}
Fields
  • dataarray of object
    19 fields in data
    • idstring
    • titlestring
    • amountnumber
    • statusstring

      One ofpendingverifiedpaidheldclosed

    • verificationSourcestring · nullable
    • verificationMethodstring

      One ofunverifiedgithubmanualseed

    • verificationStatusstring

      One ofunverifiedverifiednot_mergedunavailablefailed

    • verificationCheckedAtstring · nullable
    • verifiedAtstring · nullable
    • verificationDetailobject
    • verifiedboolean
    • decidedAtstring · nullable
    • settledAtstring · nullable
    • closedAtstring · nullable

      When a person closed the milestone without paying it (status closed), else null.

    • closeReasonstring · nullable

      The reason the person gave for closing it without paying, else null.

    • agentReasoningstring · nullable
    • txHashstring · nullable

      An on-chain hash when the payment settled on Arc, else null.

    • contractorobject · nullable
      3 fields in contractor
      • idstring
      • namestring
      • riskLevelstring
    • createdAtstring
  • pageobject

    Where this page sits in the collection.

    3 fields in page
    • nextCursorstring · nullable

      Pass back as ?cursor= to continue. Null when the end is reached.

    • hasMoreboolean

      Whether another page follows this one.

    • countinteger

      How many items this response carries.

Errors

StatusCodeWhen
400invalid_requestAn 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.
401unauthorizedNo key, or a malformed, unknown or revoked one: "A valid API key is required."
403forbiddenThe 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."
500internalAn unexpected server error. Implementation details are not exposed.