{"openapi":"3.1.0","info":{"title":"Vestiarion API","version":"v1","description":"Read a workspace's ledger, books, counterparties, milestones, treasury and insights, and add counterparties, invoices, milestones and payee links, with a workspace API key."},"servers":[{"url":"https://www.vestiarion.xyz"}],"components":{"schemas":{"ApiError":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","not_found","invalid_request","conflict","rate_limited","unavailable","internal"],"description":"One of a closed set, so a client can branch on it without parsing the message."},"message":{"type":"string","description":"A human-readable explanation. Never carries internal detail."}},"required":["code","message"]}},"required":["error"],"description":"Every error the API returns has this shape."},"GetStatusResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"businessName":{"type":"string","description":"The workspace's name."},"provenance":{"type":"object","properties":{"payments":{"type":"string","enum":["live","simulate","unavailable"]},"yield":{"type":"string","enum":["live","simulate","unavailable"]},"screening":{"type":"string","enum":["live","simulate"]}},"required":["payments","yield","screening"],"description":"Payments and yield differ and are reported separately, as in the UI. `unavailable` means the workspace's Circle credentials are stored but could not be read: cycles refuse to pay then rather than simulate, so neither leg is live or simulated."},"clock":{"type":"object","properties":{"mode":{"type":"string","enum":["real","simulate"]},"day":{"type":"number"},"lastCycleAt":{"type":["string","null"]}},"required":["mode","day","lastCycleAt"],"description":"The workspace's clock, and when its last cycle ran."},"totals":{"type":"object","properties":{"decisionsLogged":{"type":"number"},"totalPaidOut":{"type":"number"},"flagged":{"type":"number"}},"required":["decisionsLogged","totalPaidOut","flagged"],"description":"Running totals across the workspace."},"configuration":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"What is configured for this workspace, as flags and modes. Never carries a secret."},"apiVersion":{"type":"string","const":"v1"}},"required":["businessName","provenance","clock","totals","configuration","apiVersion"],"description":"What this workspace is, and what it can actually do."}},"required":["data"]},"ListLedgerEntriesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"seq":{"type":"number","description":"Monotonic within a workspace, but not gap-free; the hash chain proves continuity."},"id":{"type":"string"},"ts":{"type":"string"},"actor":{"type":"string"},"domain":{"type":"string"},"action":{"type":"string"},"summary":{"type":"string"},"detail":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"bodyHash":{"type":"string","description":"Present so a consumer can verify the chain itself rather than trust us."},"signature":{"type":"string"},"prevHash":{"type":"string"},"hash":{"type":"string"},"signingKeyId":{"description":"Which key signed the entry; `null` for entries written before key identity existed. A consumer verifying for itself needs this to pick the right key.","type":["string","null"]}},"required":["seq","id","ts","actor","domain","action","summary","detail","bodyHash","signature","prevHash","hash","signingKeyId"],"description":"One entry of the audit chain, which the API returns oldest first."}},"page":{"type":"object","properties":{"nextCursor":{"description":"Pass back as `?cursor=` to continue. Null when the end is reached.","type":["string","null"]},"hasMore":{"type":"boolean","description":"Whether another page follows this one."},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many items this response carries."}},"required":["nextCursor","hasMore","count"],"description":"Where this page sits in the collection."}},"required":["data","page"]},"VerifyLedgerResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"valid":{"description":"`true` verified, `false` broken, and `null` not checked, which is a third answer, not a soft failure. A workspace holding no public key has produced no evidence either way.","type":["boolean","null"]},"checkedEntries":{"type":"number"},"brokenAt":{"description":"The `seq` of the first entry that failed. Absent unless `valid` is `false`.","type":"number"},"reason":{"description":"Why the verdict is what it is, when it is not a plain `true`.","type":"string"},"warnings":{"description":"Configuration problems found on the way to this verdict; not about the chain.","type":"array","items":{"type":"string"}}},"required":["valid","checkedEntries"],"description":"The verdict of replaying the workspace's ledger: signatures, body hashes and hash continuity."}},"required":["data"]},"ListInvoicesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"direction":{"type":"string","enum":["payable","receivable"]},"status":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string","description":"USDC or EURC: what `amount` is in, and what a payable is paid in. A EURC payable is checked against the counterparty's USDC limit at a quoted rate."},"memo":{"type":["string","null"]},"poReference":{"type":["string","null"]},"goodsReceived":{"type":"boolean"},"dueDate":{"type":"string"},"scheduledFor":{"description":"ISO timestamp the agent has committed to pay this on, once scheduled; else null.","type":["string","null"]},"earlyPayDiscount":{"anyOf":[{"type":"object","properties":{"percent":{"type":"number"},"deadline":{"type":"string"}},"required":["percent","deadline"]},{"type":"null"}],"description":"The early-payment discount this invoice carries, if any: the percent off and the deadline's ISO timestamp."},"decidedAt":{"type":["string","null"]},"settledAt":{"type":["string","null"]},"escalatedAt":{"type":["string","null"]},"agentReasoning":{"description":"Why the agent ruled as it did, verbatim from the decision.","type":["string","null"]},"txHash":{"description":"An on-chain hash once the payment settled, else null: on Arc testnet, or for a payout from a Gateway balance the mint on the payee's chain.","type":["string","null"]},"paidAmount":{"description":"What actually left once this invoice was paid; null otherwise, even while a submitted transfer already carries an amount.","type":["number","null"]},"counterparty":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"riskLevel":{"type":"string"}},"required":["id","name","riskLevel"]},{"type":"null"}]},"createdAt":{"type":"string"}},"required":["id","direction","status","amount","currency","memo","poReference","goodsReceived","dueDate","scheduledFor","earlyPayDiscount","decidedAt","settledAt","escalatedAt","agentReasoning","txHash","paidAmount","counterparty","createdAt"],"description":"An invoice in the payable or receivable book, with the agent's reasoning."}},"page":{"type":"object","properties":{"nextCursor":{"description":"Pass back as `?cursor=` to continue. Null when the end is reached.","type":["string","null"]},"hasMore":{"type":"boolean","description":"Whether another page follows this one."},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many items this response carries."}},"required":["nextCursor","hasMore","count"],"description":"Where this page sits in the collection."}},"required":["data","page"]},"CreateInvoiceResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"direction":{"type":"string","enum":["payable","receivable"]},"status":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string","description":"USDC or EURC: what `amount` is in, and what a payable is paid in. A EURC payable is checked against the counterparty's USDC limit at a quoted rate."},"memo":{"type":["string","null"]},"poReference":{"type":["string","null"]},"goodsReceived":{"type":"boolean"},"dueDate":{"type":"string"},"scheduledFor":{"description":"ISO timestamp the agent has committed to pay this on, once scheduled; else null.","type":["string","null"]},"earlyPayDiscount":{"anyOf":[{"type":"object","properties":{"percent":{"type":"number"},"deadline":{"type":"string"}},"required":["percent","deadline"]},{"type":"null"}],"description":"The early-payment discount this invoice carries, if any: the percent off and the deadline's ISO timestamp."},"decidedAt":{"type":["string","null"]},"settledAt":{"type":["string","null"]},"escalatedAt":{"type":["string","null"]},"agentReasoning":{"description":"Why the agent ruled as it did, verbatim from the decision.","type":["string","null"]},"txHash":{"description":"An on-chain hash once the payment settled, else null: on Arc testnet, or for a payout from a Gateway balance the mint on the payee's chain.","type":["string","null"]},"paidAmount":{"description":"What actually left once this invoice was paid; null otherwise, even while a submitted transfer already carries an amount.","type":["number","null"]},"counterparty":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"riskLevel":{"type":"string"}},"required":["id","name","riskLevel"]},{"type":"null"}]},"createdAt":{"type":"string"}},"required":["id","direction","status","amount","currency","memo","poReference","goodsReceived","dueDate","scheduledFor","earlyPayDiscount","decidedAt","settledAt","escalatedAt","agentReasoning","txHash","paidAmount","counterparty","createdAt"],"description":"An invoice in the payable or receivable book, with the agent's reasoning."}},"required":["data"]},"CreateInvoiceRequest":{"type":"object","properties":{"direction":{"description":"`payable`, a bill the business pays, which is the default, or `receivable`, one it is owed.","type":"string","enum":["payable","receivable"]},"counterpartyId":{"type":"string","description":"The counterparty's `id`, from `GET /api/v1/counterparties` or from the answer that added it."},"amount":{"description":"What it bills, in `currency`, with at most 6 decimal places. A decimal string such as `\"1250.50\"` keeps it exact; a number is read the same way.","type":["string","number"]},"currency":{"description":"`USDC`, the default, or `EURC`.","type":"string","enum":["USDC","EURC"]},"dueDate":{"type":"string","description":"The day it is due, as `YYYY-MM-DD`."},"memo":{"description":"What it is for, up to 280 characters.","type":"string"},"poReference":{"description":"The purchase order it bills against, up to 100 characters.","type":"string"},"goodsReceived":{"description":"Whether what it bills for has arrived. Defaults to `false`. Without it, or without `poReference`, the agent asks for the missing detail instead of paying.","type":"boolean"},"earlyPayDiscount":{"description":"A discount for paying by `deadline`. The agent weighs it against what the cash would earn in the reserve until `dueDate`.","type":"object","properties":{"percent":{"description":"The percent off, greater than 0 and less than 100, with at most 2 decimal places.","type":["string","number"]},"deadline":{"type":"string","description":"The last day it applies, as `YYYY-MM-DD`, on or before `dueDate`."}},"required":["percent","deadline"],"additionalProperties":false}},"required":["counterpartyId","amount","dueDate"],"additionalProperties":false,"description":"An invoice to add. The agent decides a payable as one typed in, with every guardrail, usually within a minute."},"ListCounterpartiesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["vendor","client","contractor"]},"address":{"type":["string","null"]},"chain":{"type":["string","null"]},"jurisdiction":{"type":["string","null"]},"riskLevel":{"type":"string","enum":["unscreened","clear","medium","high"]},"riskNotes":{"type":["string","null"]},"baselinePaymentLimit":{"description":"The business's baseline payment limit for this counterparty.","type":["number","null"]},"paymentLimit":{"description":"The current payment limit, derived from the risk tier.","type":["number","null"]},"lastScreenedAt":{"type":["string","null"]},"performanceScore":{"description":"No history is different from a zero score and remains null.","type":["number","null"]},"performanceInputs":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"createdAt":{"type":"string"}},"required":["id","name","role","address","chain","jurisdiction","riskLevel","riskNotes","baselinePaymentLimit","paymentLimit","lastScreenedAt","performanceScore","performanceInputs","createdAt"],"description":"A vendor, client or contractor, with its risk tier and payment limits."}},"page":{"type":"object","properties":{"nextCursor":{"description":"Pass back as `?cursor=` to continue. Null when the end is reached.","type":["string","null"]},"hasMore":{"type":"boolean","description":"Whether another page follows this one."},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many items this response carries."}},"required":["nextCursor","hasMore","count"],"description":"Where this page sits in the collection."}},"required":["data","page"]},"GetCounterpartyResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["vendor","client","contractor"]},"address":{"type":["string","null"]},"chain":{"type":["string","null"]},"jurisdiction":{"type":["string","null"]},"riskLevel":{"type":"string","enum":["unscreened","clear","medium","high"]},"riskNotes":{"type":["string","null"]},"baselinePaymentLimit":{"description":"The business's baseline payment limit for this counterparty.","type":["number","null"]},"paymentLimit":{"description":"The current payment limit, derived from the risk tier.","type":["number","null"]},"lastScreenedAt":{"type":["string","null"]},"performanceScore":{"description":"No history is different from a zero score and remains null.","type":["number","null"]},"performanceInputs":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"createdAt":{"type":"string"},"screeningHistory":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"riskLevel":{"type":"string"},"source":{"type":"string"},"notes":{"type":["string","null"]},"rawScore":{"type":["number","null"]},"matchedEntityId":{"type":["string","null"]},"screeningMode":{"type":"string","enum":["live","simulate"]},"status":{"type":"string","enum":["complete","failed"]},"createdAt":{"type":"string"}},"required":["id","riskLevel","source","notes","rawScore","matchedEntityId","screeningMode","status","createdAt"],"description":"One compliance screening of a counterparty."},"description":"Up to 20 recent screenings, newest first."}},"required":["id","name","role","address","chain","jurisdiction","riskLevel","riskNotes","baselinePaymentLimit","paymentLimit","lastScreenedAt","performanceScore","performanceInputs","createdAt","screeningHistory"],"description":"A counterparty, with its recent screening history."}},"required":["data"]},"CreateCounterpartyResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["vendor","client","contractor"]},"address":{"type":["string","null"]},"chain":{"type":["string","null"]},"jurisdiction":{"type":["string","null"]},"riskLevel":{"type":"string","enum":["unscreened","clear","medium","high"]},"riskNotes":{"type":["string","null"]},"baselinePaymentLimit":{"description":"The business's baseline payment limit for this counterparty.","type":["number","null"]},"paymentLimit":{"description":"The current payment limit, derived from the risk tier.","type":["number","null"]},"lastScreenedAt":{"type":["string","null"]},"performanceScore":{"description":"No history is different from a zero score and remains null.","type":["number","null"]},"performanceInputs":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"createdAt":{"type":"string"}},"required":["id","name","role","address","chain","jurisdiction","riskLevel","riskNotes","baselinePaymentLimit","paymentLimit","lastScreenedAt","performanceScore","performanceInputs","createdAt"],"description":"A vendor, client or contractor, with its risk tier and payment limits."}},"required":["data"]},"CreateCounterpartyRequest":{"type":"object","properties":{"name":{"type":"string","description":"2 to 160 characters."},"role":{"type":"string","enum":["vendor","client","contractor"],"description":"`vendor` or `contractor`, whom the business pays, or `client`, who pays the business."},"address":{"description":"Where the agent pays it. An address added through the API waits for a person in the workspace to confirm it on Counterparties; until then the agent pays nothing to it.","type":"string","pattern":"^0x[0-9a-fA-F]{40}$"},"chain":{"description":"The chain the address receives on. Defaults to `ARC-TESTNET`; only a vendor can be paid on another chain.","type":"string","enum":["ARC-TESTNET","BASE-SEPOLIA","ARB-SEPOLIA","ETH-SEPOLIA"]},"jurisdiction":{"description":"Where it is based, up to 80 characters; screening uses it.","type":"string"},"paymentLimit":{"description":"The most the agent pays it in one payment, in USDC, with up to 6 decimal places. Required for a vendor or a contractor.","type":["string","number"]},"noticeEmail":{"description":"Where it is emailed once a payment to it is confirmed.","type":"string"}},"required":["name","role"],"additionalProperties":false,"description":"A counterparty to add. It is screened as one added in the console."},"CreatePayeeLinkResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","description":"The link's own id. It is not the link: that is `url`."},"counterpartyId":{"type":"string"},"url":{"type":"string","description":"The one-time page where the payee enters their address. It is in this answer only: Vestiarion keeps just its hash. Send it to the payee yourself."},"expiresAt":{"type":"string","description":"When the link stops working, 7 days after it was made. It also stops once the payee has used it, or a newer link replaces it."}},"required":["id","counterpartyId","url","expiresAt"],"description":"A one-time link for a payee to enter the address they are paid at. That address waits for a person in the workspace to confirm it before the agent pays to it."}},"required":["data"]},"CreatePayeeLinkRequest":{"type":"object","properties":{"counterpartyId":{"type":"string","description":"The `id` of the vendor or contractor who is to enter the address they are paid at. A client gets no link: the agent never pays one."}},"required":["counterpartyId"],"additionalProperties":false,"description":"Who the link is for."},"ListMilestonesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"amount":{"type":"number"},"status":{"type":"string","enum":["pending","verified","paid","held","closed"]},"verificationSource":{"type":["string","null"]},"verificationMethod":{"type":"string","enum":["unverified","github","manual","seed"]},"verificationStatus":{"type":"string","enum":["unverified","verified","not_merged","unavailable","failed"]},"verificationCheckedAt":{"type":["string","null"]},"verifiedAt":{"type":["string","null"]},"verificationDetail":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"verified":{"type":"boolean"},"decidedAt":{"type":["string","null"]},"settledAt":{"type":["string","null"]},"closedAt":{"description":"When a person closed the milestone without paying it (status closed), else null.","type":["string","null"]},"closeReason":{"description":"The reason the person gave for closing it without paying, else null.","type":["string","null"]},"agentReasoning":{"type":["string","null"]},"txHash":{"description":"An on-chain hash when the payment settled on Arc, else null.","type":["string","null"]},"contractor":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"riskLevel":{"type":"string"}},"required":["id","name","riskLevel"]},{"type":"null"}]},"createdAt":{"type":"string"}},"required":["id","title","amount","status","verificationSource","verificationMethod","verificationStatus","verificationCheckedAt","verifiedAt","verificationDetail","verified","decidedAt","settledAt","closedAt","closeReason","agentReasoning","txHash","contractor","createdAt"],"description":"A contractor milestone, how it was verified, and whether it was paid."}},"page":{"type":"object","properties":{"nextCursor":{"description":"Pass back as `?cursor=` to continue. Null when the end is reached.","type":["string","null"]},"hasMore":{"type":"boolean","description":"Whether another page follows this one."},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many items this response carries."}},"required":["nextCursor","hasMore","count"],"description":"Where this page sits in the collection."}},"required":["data","page"]},"CreateMilestoneResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"amount":{"type":"number"},"status":{"type":"string","enum":["pending","verified","paid","held","closed"]},"verificationSource":{"type":["string","null"]},"verificationMethod":{"type":"string","enum":["unverified","github","manual","seed"]},"verificationStatus":{"type":"string","enum":["unverified","verified","not_merged","unavailable","failed"]},"verificationCheckedAt":{"type":["string","null"]},"verifiedAt":{"type":["string","null"]},"verificationDetail":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"verified":{"type":"boolean"},"decidedAt":{"type":["string","null"]},"settledAt":{"type":["string","null"]},"closedAt":{"description":"When a person closed the milestone without paying it (status closed), else null.","type":["string","null"]},"closeReason":{"description":"The reason the person gave for closing it without paying, else null.","type":["string","null"]},"agentReasoning":{"type":["string","null"]},"txHash":{"description":"An on-chain hash when the payment settled on Arc, else null.","type":["string","null"]},"contractor":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"riskLevel":{"type":"string"}},"required":["id","name","riskLevel"]},{"type":"null"}]},"createdAt":{"type":"string"}},"required":["id","title","amount","status","verificationSource","verificationMethod","verificationStatus","verificationCheckedAt","verifiedAt","verificationDetail","verified","decidedAt","settledAt","closedAt","closeReason","agentReasoning","txHash","contractor","createdAt"],"description":"A contractor milestone, how it was verified, and whether it was paid."}},"required":["data"]},"CreateMilestoneRequest":{"type":"object","properties":{"contractorId":{"type":"string","description":"The `id` of the contractor or vendor to pay, from `GET /api/v1/counterparties` or from the answer that added it. A client is not paid for milestones."},"title":{"type":"string","description":"What was delivered, 3 to 160 characters."},"amount":{"description":"What the work is paid, in USDC, with at most 6 decimal places. A decimal string such as `\"250.00\"` keeps it exact; a number is read the same way.","type":["string","number"]},"verificationSource":{"description":"A link to the delivered work: https, up to 500 characters. A GitHub pull request (`https://github.com/<owner>/<repo>/pull/<number>`) is checked by the agent, which verifies the milestone once it is merged. Any other link is evidence for the person who verifies the milestone on Contractors.","type":"string"}},"required":["contractorId","title","amount"],"additionalProperties":false,"description":"A milestone to add. It starts pending: the agent pays it only once it is verified, by GitHub or by a person, and only after its own checks."},"GetTreasuryResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"accounts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"kind":{"type":"string","enum":["operating","reserve","chain"]},"chain":{"type":"string"},"token":{"type":"string"},"address":{"type":["string","null"]},"balance":{"type":"number"},"apy":{"type":"number"}},"required":["id","name","kind","chain","token","address","balance","apy"]}},"reservePosition":{"type":"number","description":"The sum of the reserve accounts' balances."},"obligations":{"type":"object","properties":{"asOf":{"type":["string","null"]},"dueWithin7Days":{"type":["number","null"]},"dueWithin14Days":{"type":["number","null"]}},"required":["asOf","dueWithin7Days","dueWithin14Days"],"description":"From the latest cycle snapshot; null before any snapshot exists, never an invented zero."},"latestForecast":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"asOf":{"type":"string"},"horizonDays":{"type":"number"},"projectedInflow":{"type":"number"},"projectedOutflow":{"type":"number"},"liquidBalance":{"type":"number"},"recommendation":{"type":["string","null"]}},"required":["id","asOf","horizonDays","projectedInflow","projectedOutflow","liquidBalance","recommendation"]},{"type":"null"}]},"recentActions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"action":{"type":"string","enum":["sweep_to_usyc","redeem_from_usyc","rebalance"]},"amount":{"type":"number"},"fromAccountId":{"type":["string","null"]},"toAccountId":{"type":["string","null"]},"reasoning":{"type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","action","amount","fromAccountId","toAccountId","reasoning","createdAt"]},"description":"Up to 20 treasury moves, newest first."}},"required":["accounts","reservePosition","obligations","latestForecast","recentActions"],"description":"The workspace's accounts, reserve, obligations, latest forecast and recent treasury moves."}},"required":["data"]},"GetInsightsResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"transfers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"targetType":{"type":"string","enum":["invoice","milestone"]},"targetId":{"type":"string"},"txRef":{"type":"string"},"feeUsd":{"type":"number"},"feeSource":{"type":"string","enum":["chain_reported","provider_estimate","simulated_profile"]},"settledInMs":{"type":["number","null"]},"chain":{"type":"string"},"providerMode":{"type":"string","enum":["live","simulate"]},"executedAt":{"type":"string"},"status":{"type":"string"}},"required":["id","targetType","targetId","txRef","feeUsd","feeSource","settledInMs","chain","providerMode","executedAt","status"],"description":"One executed payment, with its fee and settlement time."}},"runs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"startedAt":{"type":"string"},"finishedAt":{"type":"string"},"durationMs":{"type":"number"},"decisionCount":{"type":"number"},"paidCount":{"type":"number"},"heldCount":{"type":"number"},"flaggedCount":{"type":"number"},"awaitingInfoCount":{"type":"number"},"releasedCount":{"type":"number"},"modelDecisionCount":{"type":"number"},"heuristicDecisionCount":{"type":"number"},"guardrailOverrideCount":{"type":"number"},"referenceDisagreementCount":{"description":"Model verdicts that chose a different action from the rule-based policy. Null for cycles run before the comparison existed, never zero, which would claim perfect agreement over decisions never compared.","type":["number","null"]},"status":{"type":"string","enum":["running","completed","partial","failed"],"description":"A cycle that failed partway is not a quiet cycle, and must not read as one. Its counts are real but partial: they cover the stages that ran before it stopped, and nothing after."},"failedStage":{"type":["string","null"]},"errorMessage":{"type":["string","null"]},"chainMode":{"type":"string","enum":["live","simulate"]},"screeningMode":{"type":"string","enum":["live","simulate"]}},"required":["id","startedAt","finishedAt","durationMs","decisionCount","paidCount","heldCount","flaggedCount","awaitingInfoCount","releasedCount","modelDecisionCount","heuristicDecisionCount","guardrailOverrideCount","referenceDisagreementCount","status","failedStage","errorMessage","chainMode","screeningMode"],"description":"One agent cycle: how long it took and what it decided."}},"snapshots":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"cycleRunId":{"type":"string"},"capturedAt":{"type":"string"},"totalLiquid":{"type":"number"},"openPayables":{"type":"number"},"openReceivables":{"type":"number"},"obligationsDue7d":{"type":"number"},"obligationsDue14d":{"type":"number"},"reservePosition":{"type":"number"},"chainMode":{"type":"string","enum":["live","simulate"]}},"required":["id","cycleRunId","capturedAt","totalLiquid","openPayables","openReceivables","obligationsDue7d","obligationsDue14d","reservePosition","chainMode"],"description":"The treasury position a cycle captured."}},"treasuryMoves":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"action":{"type":"string","enum":["sweep_to_usyc","redeem_from_usyc","rebalance"]},"amount":{"type":"number"},"createdAt":{"type":"string"}},"required":["id","action","amount","createdAt"],"description":"One treasury move."}},"screenings":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"counterpartyId":{"type":"string"},"counterpartyName":{"type":"string"},"riskLevel":{"type":"string"},"previousRiskLevel":{"type":["string","null"]},"tierChanged":{"type":"boolean"},"mode":{"type":"string","enum":["live","simulate"]},"source":{"type":"string"},"status":{"type":"string","enum":["complete","failed"]},"createdAt":{"type":"string"}},"required":["id","counterpartyId","counterpartyName","riskLevel","previousRiskLevel","tierChanged","mode","source","status","createdAt"],"description":"One compliance screening, and whether it changed the counterparty's risk tier."}}},"required":["transfers","runs","snapshots","treasuryMoves","screenings"],"description":"The telemetry behind the Insights charts: the most recent transfers, cycle runs, snapshots, treasury moves and screenings, each oldest first."}},"required":["data"]}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A workspace API key: vxk_<prefix>_<secret>."}}},"paths":{"/api/v1/status":{"get":{"operationId":"get-status","summary":"Get workspace status","description":"What this workspace is, and what it can actually do. The first call a client should make: whether payments and yield are live, simulated or unavailable, the workspace clock, running totals, and a description of its configuration. Secrets are never included.\n\n`unavailable` means the workspace's Circle credentials are stored but cannot be read. A cycle refuses to pay in that state rather than fall back to simulation, so status does not report it as `simulate`.","tags":["Workspace"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetStatusResponse"},"example":{"data":{"businessName":"Vestiarion workspace","provenance":{"payments":"live","yield":"simulate","screening":"simulate"},"clock":{"mode":"simulate","day":25,"lastCycleAt":"2026-09-24T18:33:04.546517+00:00"},"totals":{"decisionsLogged":77,"totalPaidOut":4.815,"flagged":1},"configuration":{"businessName":"Vestiarion workspace","chain":{"circleConfigured":true,"arcRpcConfigured":false},"llm":{"pinned":null,"available":["deepseek"]},"compliance":{"mode":"bundled","rescreenIntervalHours":0},"followUp":{"staleAfterDays":3,"reEscalateAfterDays":7},"ledgerSigningKeyProvided":false,"githubTokenProvided":false,"clockMode":"simulate"},"apiVersion":"v1"}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/ledger":{"get":{"operationId":"list-ledger-entries","summary":"List ledger entries","description":"The audit chain, oldest first, as a resumable stream. Because the ledger is append-only and ascending by `seq`, a stored `page.nextCursor` is a watermark: a request from it never returns an entry before it. Persist the last non-null `nextCursor` only after processing every entry in the responses read, and resume from it; the last page, which had no cursor of its own, is returned again, so de-duplicate on `seq`.\n\n`seq` is monotonic within a workspace but not gap-free; continuity is proven by the hash chain, not by `seq`.","tags":["Ledger"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many items to return. Defaults to 50; a larger value is capped at 200.","schema":{"type":"integer","default":50,"minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"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`.","schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"description":"Only entries in this domain.","schema":{"type":"string"},"example":"system"},{"name":"actor","in":"query","required":false,"description":"Only entries written by this actor.","schema":{"type":"string"},"example":"system"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListLedgerEntriesResponse"},"example":{"data":[{"seq":82,"id":"4566714f-a9f0-42c8-bcd4-d89adf830806","ts":"2026-09-24T11:55:00.370366+00:00","actor":"system","domain":"system","action":"seed","summary":"Seeded demo business: Northstar Studio","detail":{"accounts":3,"invoices":6,"milestones":3,"amountScale":0.001,"counterparties":7},"bodyHash":"8780d07cb3d083d359119e58fd4783f5e4b32aac14e0a8d9f7a5bb13365a4537","signature":"c14f06b751d31be6566ed11676d60d2db731ab8bbc5972f79d0a0c131e9e37200303d5b3ad04993b7973b1ce7200e7214e5a9b511306fa30538f072eb0d34705","prevHash":"0000000000000000000000000000000000000000000000000000000000000000","hash":"b0ac72908868ddd5ed4722fd8a14ff4a844eee4dad382c5c85288bca73737669","signingKeyId":null}],"page":{"nextCursor":"eyJrIjo4Mn0","hasMore":true,"count":1}}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/ledger/verify":{"get":{"operationId":"verify-ledger","summary":"Verify the ledger","description":"Replays signatures, body hashes and hash-chain continuity for the workspace the calling key belongs to.\n\n`valid` has three values, not two. `true` verified and `false` broken are findings about the chain; `null` means no verdict was produced, because there was no key to check authorship against. `reason` says which case it is. A key that is stored but cannot be read is a configuration problem, reported in `warnings`, not a finding about the chain.","tags":["Ledger"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyLedgerResponse"},"example":{"data":{"valid":true,"checkedEntries":99}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/invoices":{"get":{"operationId":"list-invoices","summary":"List invoices","description":"The payable and receivable book, newest first, with the row id breaking equal timestamps. Each invoice carries the agent's reasoning, not only its verdict. Only a transaction reference beginning with `0x` is exposed as `txHash`; a simulated receipt gives `null`.\n\nAn unknown `direction` or `status` is refused with `400` rather than ignored.","tags":["Payables and receivables"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many items to return. Defaults to 50; a larger value is capped at 200.","schema":{"type":"integer","default":50,"minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"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`.","schema":{"type":"string"}},{"name":"direction","in":"query","required":false,"description":"Only payables, or only receivables.","schema":{"type":"string","enum":["payable","receivable"]}},{"name":"status","in":"query","required":false,"description":"Only invoices in this status.","schema":{"type":"string","enum":["pending","matched","scheduled","paid","held","flagged","awaiting_info","received","rejected"]}},{"name":"counterpartyId","in":"query","required":false,"description":"Only invoices from or to this counterparty.","schema":{"type":"string"},"example":"4e363b59-d1ca-4425-924c-5c894bc3373f"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListInvoicesResponse"},"example":{"data":[{"id":"9440f32c-000d-4a63-97f1-4eb6bf78439f","direction":"payable","status":"paid","amount":0.11,"currency":"USDC","memo":"Stage-isolation verification","poReference":"PO-4001","goodsReceived":true,"dueDate":"2026-09-28T15:22:48.928+00:00","scheduledFor":null,"earlyPayDiscount":null,"decidedAt":"2026-09-24T15:24:22.75+00:00","settledAt":"2026-09-24T15:24:22.75+00:00","escalatedAt":null,"agentReasoning":"Three-way match is complete: PO-4001 is on file and goodsReceived is true. Counterparty Vercel Inc has riskLevel 'clear' (not high) and the invoice amount 0.11 USDC is below the counterparty payment limit of 2 USDC. Treasury operatingBalance is 22.875 USDC, leaving 22.765 USDC after payment, and no duplicate matches were found (duplicateNote confirms no earlier payable from this counterparty resembles this invoice), so there is no fraud indicator.","txHash":"0xda97ba74aca6a45e4759858230e743aac0735252b874fb07c20ec8026d80a7bf","paidAmount":0.11,"counterparty":{"id":"4e363b59-d1ca-4425-924c-5c894bc3373f","name":"Vercel Inc","riskLevel":"clear"},"createdAt":"2026-09-24T15:22:50.176754+00:00"}],"page":{"nextCursor":"eyJrIjoiMjAyNi0wOS0yNFQxNToyMjo1MC4xNzY3NTQrMDA6MDAiLCJpZCI6Ijk0NDBmMzJjLTAwMGQtNGE2My05N2YxLTRlYjZiZjc4NDM5ZiJ9","hasMore":true,"count":1}}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"operationId":"create-invoice","summary":"Add an invoice","description":"Adds a payable or a receivable, checked by the rules of the console's invoice form, and recorded in the ledger as `create_invoice` with `via: \"api\"` and the key's id. It is added as the key's issuer's: if the agent holds it, the issuer cannot approve it, unless they are the workspace's only approver.\n\nThe agent decides a payable as one typed in, with every guardrail and the workspace's limits, usually within a minute. The API never approves or pays. A `counterpartyId` the workspace does not hold, including another workspace's, answers `400`.","tags":["Payables and receivables"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: up to 255 printable ASCII characters, unique to the record being added, such as its id in your own system. A repeat with the same key and the same body within 24 hours gets the first answer back, with `Idempotent-Replayed: true`, and adds nothing. The same key with a different body answers `409`.","schema":{"type":"string"},"example":"billing-inv-2026-0042"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvoiceRequest"},"example":{"counterpartyId":"6b361405-cfda-4400-a286-364b561911ce","amount":"0.10","dueDate":"2026-10-03","poReference":"PO-API-1","goodsReceived":true}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvoiceResponse"},"example":{"data":{"id":"1f96fd0b-71de-41bf-b088-779655ea6df4","direction":"payable","status":"pending","amount":0.1,"currency":"USDC","memo":null,"poReference":"PO-API-1","goodsReceived":true,"dueDate":"2026-10-03T12:00:00+00:00","scheduledFor":null,"earlyPayDiscount":null,"decidedAt":null,"settledAt":null,"escalatedAt":null,"agentReasoning":null,"txHash":null,"paidAmount":null,"counterparty":{"id":"6b361405-cfda-4400-a286-364b561911ce","name":"API Test Vendor","riskLevel":"clear"},"createdAt":"2026-10-03T10:16:16.374931+00:00"}}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/counterparties":{"get":{"operationId":"list-counterparties","summary":"List counterparties","description":"Vendors, clients and contractors, newest first, with the row id breaking equal timestamps. Both the business's baseline payment limit and the current limit derived from the risk tier are reported. `performanceScore` is `null` when there is no history.","tags":["Counterparties"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many items to return. Defaults to 50; a larger value is capped at 200.","schema":{"type":"integer","default":50,"minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"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`.","schema":{"type":"string"}},{"name":"role","in":"query","required":false,"description":"Only counterparties with this role.","schema":{"type":"string","enum":["vendor","client","contractor"]}},{"name":"riskLevel","in":"query","required":false,"description":"Only counterparties at this risk tier.","schema":{"type":"string","enum":["unscreened","clear","medium","high"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCounterpartiesResponse"},"example":{"data":[{"id":"dc5e5751-3287-46c9-8bd1-83a42ab02699","name":"Anthropic API Services","role":"vendor","address":"0x90a5821e8a59b711777c49d11a283c9c76cd811e","chain":"ARC-TESTNET","jurisdiction":null,"riskLevel":"clear","riskNotes":"No match against watchlist","baselinePaymentLimit":5,"paymentLimit":5,"lastScreenedAt":"2026-09-24T18:32:57.327+00:00","performanceScore":0.667,"performanceInputs":{"heldOrFlagged":0,"heldByOurPolicy":1,"riskTierChanges":0,"duplicateSubmissions":0,"informationRequested":0,"paidWithoutIntervention":1},"createdAt":"2026-09-24T11:54:57.677284+00:00"}],"page":{"nextCursor":"eyJrIjoiMjAyNi0wOS0yNFQxMTo1NDo1Ny42NzcyODQrMDA6MDAiLCJpZCI6ImRjNWU1NzUxLTMyODctNDZjOS04YmQxLTgzYTQyYWIwMjY5OSJ9","hasMore":true,"count":1}}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"operationId":"create-counterparty","summary":"Add a counterparty","description":"Adds a vendor, contractor or client, checked by the rules of the console's form and screened as one added there: the answer's `riskLevel` is the screening's verdict, or `unscreened` when screening could not finish. It is recorded in the ledger as `create_counterparty` with `via: \"api\"` and the key's id.\n\nAn address added through the API waits for a person. The agent pays nothing to it until an owner, admin or approver confirms it on Counterparties, so a key can add records but cannot point the agent's payments at a new address.","tags":["Counterparties"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: up to 255 printable ASCII characters, unique to the record being added, such as its id in your own system. A repeat with the same key and the same body within 24 hours gets the first answer back, with `Idempotent-Replayed: true`, and adds nothing. The same key with a different body answers `409`.","schema":{"type":"string"},"example":"crm-vendor-1042"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCounterpartyRequest"},"example":{"name":"API Test Vendor","role":"vendor","address":"0x6b3A4C65f362b818bb7FD6f999477A03CE07e51a","paymentLimit":"1"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCounterpartyResponse"},"example":{"data":{"id":"6b361405-cfda-4400-a286-364b561911ce","name":"API Test Vendor","role":"vendor","address":"0x6b3A4C65f362b818bb7FD6f999477A03CE07e51a","chain":"ARC-TESTNET","jurisdiction":null,"riskLevel":"clear","riskNotes":"OpenSanctions returned no matching entity","baselinePaymentLimit":1,"paymentLimit":1,"lastScreenedAt":"2026-10-03T10:15:29.759+00:00","performanceScore":null,"performanceInputs":null,"createdAt":"2026-10-03T10:15:26.865688+00:00"}}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/counterparties/{id}":{"get":{"operationId":"get-counterparty","summary":"Get a counterparty","description":"One counterparty, with up to 20 recent compliance screenings, newest first. An id this workspace does not hold, including another workspace's, answers `404`.","tags":["Counterparties"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The counterparty's id.","schema":{"type":"string"},"example":"dc5e5751-3287-46c9-8bd1-83a42ab02699"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCounterpartyResponse"},"example":{"data":{"id":"dc5e5751-3287-46c9-8bd1-83a42ab02699","name":"Anthropic API Services","role":"vendor","address":"0x90a5821e8a59b711777c49d11a283c9c76cd811e","chain":"ARC-TESTNET","jurisdiction":null,"riskLevel":"clear","riskNotes":"No match against watchlist","baselinePaymentLimit":5,"paymentLimit":5,"lastScreenedAt":"2026-09-24T18:32:57.327+00:00","performanceScore":0.667,"performanceInputs":{"heldOrFlagged":0,"heldByOurPolicy":1,"riskTierChanges":0,"duplicateSubmissions":0,"informationRequested":0,"paidWithoutIntervention":1},"createdAt":"2026-09-24T11:54:57.677284+00:00","screeningHistory":[{"id":"d49b558b-199f-46d5-a43e-ae2af3ad9c49","riskLevel":"clear","source":"simulated-sanctions-list","notes":"No match against watchlist","rawScore":null,"matchedEntityId":null,"screeningMode":"simulate","status":"complete","createdAt":"2026-09-24T18:32:58.403732+00:00"}]}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/payee-links":{"post":{"operationId":"create-payee-link","summary":"Create a payee link","description":"Makes a one-time link where a vendor or contractor enters the address they are paid at, recorded in the ledger as `payee_link_created` with `via: \"api\"` and the key's id. Send `url` to the payee yourself. It is in this answer only, since Vestiarion keeps just its hash, and the answer is sent with `Cache-Control: no-store`. The link works once and expires after 7 days.\n\nThe address the payee enters waits for a person in the workspace to confirm it on Counterparties; until then the agent pays nothing to it. Making a link revokes the payee's unused one, so only the newest works. For the same reason this operation keeps no outcome for an `Idempotency-Key`, which would store the link: a repeat makes a new link. A `counterpartyId` the workspace does not hold, or a client's, answers `400`.","tags":["Counterparties"],"security":[{"bearerAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePayeeLinkRequest"},"example":{"counterpartyId":"26d6ffed-356d-474a-8d42-89bc942f6b4e"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePayeeLinkResponse"},"example":{"data":{"id":"0810c2f3-dc6b-487e-aff5-63297ad33813","counterpartyId":"26d6ffed-356d-474a-8d42-89bc942f6b4e","url":"https://www.vestiarion.xyz/payee/vxp_avUyHXYqUlnt1OMB323j4N6Xv3H5lKzjZRNvbm1hfc4","expiresAt":"2026-10-10T15:42:04.28+00:00"}}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/milestones":{"get":{"operationId":"list-milestones","summary":"List milestones","description":"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`.","tags":["Milestones"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many items to return. Defaults to 50; a larger value is capped at 200.","schema":{"type":"integer","default":50,"minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"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`.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Only milestones in this status.","schema":{"type":"string","enum":["pending","verified","paid","held","closed"]}},{"name":"contractorId","in":"query","required":false,"description":"Only milestones for this contractor.","schema":{"type":"string"},"example":"5541f1a4-4e48-4fa5-880c-9ffc97d8953b"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListMilestonesResponse"},"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}}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"operationId":"create-milestone","summary":"Add a milestone","description":"Adds work a contractor is to be paid for, checked by the rules of the console's Add milestone form, and recorded in the ledger as `create_milestone` with `via: \"api\"` and the key's id. It is added as the key's issuer's: if the agent holds it on its own judgment, someone other than the issuer must choose Pay now, unless the issuer is the workspace's only approver.\n\nIt starts `pending`, and the API cannot verify it. A GitHub pull request in `verificationSource` is checked by the agent, which verifies the milestone once the pull request is merged; any other link is evidence for the person who verifies it on Contractors. Once it is verified, the agent decides the payment with every guardrail, and pays only to the contractor's confirmed address. A `contractorId` the workspace does not hold, or a client's, answers `400`.","tags":["Milestones"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: up to 255 printable ASCII characters, unique to the record being added, such as its id in your own system. A repeat with the same key and the same body within 24 hours gets the first answer back, with `Idempotent-Replayed: true`, and adds nothing. The same key with a different body answers `409`.","schema":{"type":"string"},"example":"ci-bounty-pr-176"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMilestoneRequest"},"example":{"contractorId":"26d6ffed-356d-474a-8d42-89bc942f6b4e","title":"TypeScript SDK for the API","amount":"0.10","verificationSource":"https://github.com/duongnq2798/vestiarion/pull/176"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMilestoneResponse"},"example":{"data":{"id":"354132aa-e7f6-46f8-ae3c-aa6809f9b9b6","title":"TypeScript SDK for the API","amount":0.1,"status":"pending","verificationSource":"https://github.com/duongnq2798/vestiarion/pull/176","verificationMethod":"unverified","verificationStatus":"unverified","verificationCheckedAt":null,"verifiedAt":null,"verificationDetail":{},"verified":false,"decidedAt":null,"settledAt":null,"closedAt":null,"closeReason":null,"agentReasoning":null,"txHash":null,"contractor":{"id":"26d6ffed-356d-474a-8d42-89bc942f6b4e","name":"API Test Contractor","riskLevel":"clear"},"createdAt":"2026-10-03T15:43:09.204631+00:00"}}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/treasury":{"get":{"operationId":"get-treasury","summary":"Get the treasury","description":"The workspace's accounts and reserve position, its obligations from the latest cycle snapshot, the latest liquidity forecast, and up to 20 recent treasury moves. Obligations stay `null` before any snapshot exists; the API does not invent zeroes.","tags":["Treasury"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetTreasuryResponse"},"example":{"data":{"accounts":[{"id":"55ce33e5-4b1c-47e6-838b-2446b80300c7","name":"Base Client Wallet","kind":"chain","chain":"BASE-SEPOLIA","token":"USDC","address":"0x4d10b4076a4975650e80d087fc9c99610ca76266","balance":0,"apy":0},{"id":"6f32681d-2f32-4db2-9841-c44f9be25965","name":"Arc Operating Wallet","kind":"operating","chain":"ARC-TESTNET","token":"USDC","address":"0x2fafdda3f973e8f993911f1c2196d5e72d51d71d","balance":22.765,"apy":0},{"id":"02a3c356-9571-4d5e-992a-5672dedba590","name":"USYC Reserve","kind":"reserve","chain":"ARC-TESTNET","token":"USYC","address":"0x8c99d5b1ee35e7d02887f5064a1b3f1a78a0ab66","balance":0,"apy":0.045}],"reservePosition":0,"obligations":{"asOf":"2026-09-24T18:33:03.344+00:00","dueWithin7Days":11.2,"dueWithin14Days":11.2},"latestForecast":{"id":"73400ece-0f38-4695-9bad-3816650b71fb","asOf":"2026-09-24T18:33:03.226+00:00","horizonDays":14,"projectedInflow":9,"projectedOutflow":11.2,"liquidBalance":22.765,"recommendation":"Liquidity healthy."},"recentActions":[]}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/insights":{"get":{"operationId":"get-insights","summary":"Get insights","description":"The telemetry behind the Insights page: recent transfers, cycle runs, cycle snapshots, treasury moves and screenings. `referenceDisagreementCount: null` means the cycle predates the comparison, and `status: \"partial\"` is reported as it is, not rewritten as completed or failed.","tags":["Insights"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetInsightsResponse"},"example":{"data":{"transfers":[{"id":"359e82e1-958d-4327-9174-e0b885eebe8f","targetType":"invoice","targetId":"1d7e1714-3f84-493e-a3ea-c984a2881100","txRef":"0x36ea71ac97cad3743f227860785207e6f25148251735569be0f6b16c73130343","feeUsd":0.003248,"feeSource":"chain_reported","settledInMs":5000,"chain":"ARC-TESTNET","providerMode":"live","executedAt":"2026-09-24T11:55:24.131+00:00","status":"confirmed"}],"runs":[{"id":"8cbcf6ca-2d58-43c9-9237-3000851e7046","startedAt":"2026-09-24T11:53:06.672+00:00","finishedAt":"2026-09-24T11:53:16.101+00:00","durationMs":9429,"decisionCount":1,"paidCount":0,"heldCount":0,"flaggedCount":0,"awaitingInfoCount":0,"releasedCount":0,"modelDecisionCount":1,"heuristicDecisionCount":0,"guardrailOverrideCount":0,"referenceDisagreementCount":null,"status":"completed","failedStage":null,"errorMessage":null,"chainMode":"live","screeningMode":"simulate"},{"id":"bd76f653-4352-42b3-aec5-5ddbbe01c882","startedAt":"2026-09-24T15:22:50.871+00:00","finishedAt":"2026-09-24T15:23:00.617+00:00","durationMs":9746,"decisionCount":0,"paidCount":0,"heldCount":0,"flaggedCount":0,"awaitingInfoCount":0,"releasedCount":0,"modelDecisionCount":0,"heuristicDecisionCount":0,"guardrailOverrideCount":0,"referenceDisagreementCount":0,"status":"partial","failedStage":"ap","errorMessage":"ap: AGENT_LLM_PROVIDER=openai but OPENAI_API_KEY is not set; treasury: AGENT_LLM_PROVIDER=openai but OPENAI_API_KEY is not set","chainMode":"live","screeningMode":"simulate"}],"snapshots":[{"id":"352d94e4-a945-420f-a933-34b06b46412b","cycleRunId":"8cbcf6ca-2d58-43c9-9237-3000851e7046","capturedAt":"2026-09-24T11:53:16.101+00:00","totalLiquid":27.58,"openPayables":10.695,"openReceivables":9,"obligationsDue7d":12.195,"obligationsDue14d":12.195,"reservePosition":0,"chainMode":"live"}],"treasuryMoves":[],"screenings":[{"id":"54d6f2a8-d939-45ef-a41e-61f88fd362ae","counterpartyId":"dc5e5751-3287-46c9-8bd1-83a42ab02699","counterpartyName":"Anthropic API Services","riskLevel":"clear","previousRiskLevel":null,"tierChanged":false,"mode":"simulate","source":"simulated-sanctions-list","status":"complete","createdAt":"2026-09-24T11:55:11.147351+00:00"}]}}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"internal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}