From request to receipt.
Create a policy-bounded request, choose a qualified provider, fund work, verify the exact submission, and settle with an auditable receipt.
One package is enough
pnpm add @telaro/sdkConfigure the network, hosted API, organization session, and tenant. The API rechecks organization membership for every request.
import { createTelaro } from "@telaro/sdk";
const telaro = createTelaro({
network: "devnet",
procurementApiBase: process.env.TELARO_PROCUREMENT_API_URL,
auth: { token: organizationSession },
organizationId: "org_acme",
});TELARO_PROCUREMENT_API_URL=http://localhost:8080network: "devnet"network: "mainnet-beta"This example runs in a trusted server process. The product app keeps its bearer in an HTTP-only session and sends browser commands through a same-origin gateway. Keep each environment's API URL, access token, organization, mint, RPC, and signer configuration together. Do not mix a devnet mint with a mainnet request, and do not enable mainnet spend until its deployment is explicitly authorized and validated.
Turn an outcome into an editable draft
Gemini can structure the goal, deliverable, budget, deadline, and acceptance method. The result stays in your form until a person reviews it and explicitly creates the request.
const draft = await telaro.procurement.interpretRequest({
prompt: "Analyze support themes and rank the top retention opportunities",
currentDraft: {
maximumSpendUsd: "25",
deadline: "2026-08-12",
dataClass: "internal",
acceptanceMethod: "human",
},
});
// Show draft.goal, draft.deliverableDescription, and any
// clarifyingQuestions in an editable review screen.Create a bounded request
The request defines what can be purchased before a provider is selected or capital moves.
const request = await telaro.procurement.createRequest({
workspaceId: "ws_research",
costCenterId: "cc_market_intel",
goal: "Summarize this market report",
deliverable: {
kind: "json",
acceptanceMethod: "deterministic",
},
maximumSpend: {
currency: "USDC",
mint: devnetUsdcMint,
decimals: 6,
amountAtomic: "5000000",
cluster: "devnet",
},
deadline: "2026-08-04T09:00:00.000Z",
dataClass: "internal",
}, { idempotencyKey: crypto.randomUUID() });Put only public-safe or encrypted references in work URIs. A confidential classification does not make raw on-chain data private.
Discover and compare candidates
const comparison = await telaro.procurement.discoverCandidates(
request.id,
{ category: 4, limit: 3 },
{ idempotencyKey: crypto.randomUUID() },
);
const selected = comparison.candidates[0];
console.log(selected.provider, selected.price, selected.trust.score);Discovery applies hard price, asset, and organization-policy filters first. Signed AgentCard evidence and stable exclusion reasons remain available for audit.
const advice = await telaro.procurement.recommendCandidates(request.id, {
discoveryId: comparison.id,
});
console.log(advice.recommendedProvider);
console.log(advice.recommendations[0].summary);Gemini only sees candidates already retained by hard policy filtering. The API rejects invented or out-of-set provider IDs, and the user can keep the deterministic order or choose another eligible provider.
Freeze terms, then approve
let execution = await telaro.procurement.prepareSacpExecution(
request.id,
{
discoveryId: comparison.id,
provider: selected.provider,
offering: selected.offering!,
budgetAccountId: "budget_market_intel_usdc",
workUri: "https://tasks.acme.example/encrypted/report-42",
submitWindowSeconds: 3600,
},
{ idempotencyKey: crypto.randomUUID() },
);
if (execution.status === "approval_pending") {
execution = await approverProcurement.decideExecutionApproval(
execution.id,
{ decision: "approved", reason: "Within delegated budget." },
{ idempotencyKey: crypto.randomUUID() },
);
}Use a separate owner, admin, or approver session when policy requires approval. The approval is bound to the immutable mandate hash; changed terms require a new decision.
Reserve and execute
const funded = await telaro.procurement.executeSacp(execution.id, {
idempotencyKey: crypto.randomUUID(),
});Execution reserves budget transactionally and creates or funds the sACP job through the buyer signer boundary. A response timeout does not prove failure—inspect financialState before retrying.
Provider submits; buyer syncs
The provider process signs its own submission. It never receives the buyer's organization token or buyer signer.
import {
IdempotentSacpSubmissionAdapter,
Web3SacpProviderChainDriver,
} from "@telaro/sdk/procurement/server";
const submissions = new IdempotentSacpSubmissionAdapter(
new Web3SacpProviderChainDriver({ connection, provider: providerSigner }),
);
await submissions.ensureSubmitted({
jobId: funded.sacp!.jobId,
provider: providerSigner.publicKey.toBase58(),
submissionUri: "ipfs://bafy-provider-result",
});Once the provider transaction is observable, the buyer control plane synchronizes it.
const submitted = await telaro.procurement.syncSacpSubmission(
funded.id,
{ idempotencyKey: crypto.randomUUID() },
);Verify the exact submission, then accept
const verified = await telaro.procurement.verifySubmission(
submitted.id,
{}, // deterministic result comes from the server verifier
{ idempotencyKey: crypto.randomUUID() },
);
const terminal = verified.verification?.outcome === "passed"
? await telaro.procurement.acceptSacp(verified.id, {
idempotencyKey: crypto.randomUUID(),
})
: await telaro.procurement.disputeSacp(
verified.id,
{
reason: "The frozen acceptance contract did not pass.",
evidenceUri: "ipfs://bafy-encrypted-dispute-evidence",
},
{ idempotencyKey: crypto.randomUUID() },
);Failed or inconclusive verification cannot call acceptance. Open a dispute instead; only the frozen reason hash is written on-chain. The bound evaluator settles it, then call syncSacpVerdict.
Read the receipt
const receipt = await telaro.procurement.getReceipt(terminal.runId);
console.log(receipt.settlement.state); // "settled"
console.log(receipt.settlement.transactionSignatures);
console.log(receipt.verification?.evidence); // absent on deadline reclaim
console.log(receipt.auditRoot);The receipt links the request, frozen policy decision, approvals, provider, authorized and settled amounts, verification evidence, settlement signatures, and audit root.