---
title: "Customer-owned zero-custody ACP tender workflow"
method: POST
path: "/v1/agent/virtuals-acp"
tags: ["Session"]
---

# Customer-owned zero-custody ACP tender workflow

`POST /v1/agent/virtuals-acp`

## Request

- Base URL: `https://www.farmdash.one/api`
- URL: `https://www.farmdash.one/api/v1/agent/virtuals-acp`
- Auth: one of:
  - none
  - HTTP bearer

TollBooth commercial access/rate limits apply; a paid bearer key is optional.
Every supported action requires sessionId, agentAddress and a valid session
capability: sessionToken in the body or X-FarmDash-Session-Token header.
A nonempty header takes precedence over the body token. Authentication requires
an unexpired non-terminal session (active or paused), bound to the agent or a registered team member.
A session token authenticates the tenant; it is not customer-wallet signing authority.

The public capability remains preparation_only: API access payment does not
enable execution. Selection grants none_selection_only authority and V2
preparation returns a non-spendable none_draft_only draft. FarmDash cannot
spend the customer ACP wallet. A customer-owned connector creates/funds jobs
locally only after the exact fresh customer-wallet EIP-712 approval and all
applicable runtime prerequisites. This contract is not live qualification.

create_tender is the legacy V1 draft flow; it returns 503
acp_v1_creation_disabled unless V1 creation is explicitly enabled. It requires
an evaluator configuration, serializable task and a fresh authoritative
simulation (428 simulation_not_found_or_expired otherwise).
select_provider_plan_v2 and prepare_tender_v2 require the enabled V2 rollout
cohort and ready migrations. Selection additionally requires the authoritative
evaluator adapter, Base RPC, registry, stake/identity ingestion and identity
salt. Preparation requires evaluator identity, an unexpired unconsumed
tenant/session-bound selectionId, matching provider-plan commitments, and
tenant-bound authoritative simulation evidence. Optional providers must match
the selection exactly; they do not override it. V2 accepts a local task hash,
not plaintext task or caller-supplied economic baselines.

authorize_tender and authorize_tender_v2 require the exact locally signed
fresh V1 or Base-domain V2 tender approval, respectively. V2 also requires
unexpired analysis evidence, matching providerSelectionId, fresh independent
provider readiness and every paid-workflow prerequisite; incomplete deployment
readiness returns 503 acp_v2_paid_workflow_unready. Neither preparation nor
commercial payment bypasses those gates or grants swap/futures execution.
cancel_tender cancels only a non-spendable draft. get_tender reads owned state.
bind_job requires an authorized tender and a verified live OPEN job matching
client, role provider and evaluator. reserve_funding_v2 requires an authorized
V2 tender and that exact job budget; authority remains customer_wallet_only.
record_funding_submission_v2 records hashes for an owned V2 reservation;
submitted is not funding confirmation or evaluation availability.
evaluate_tender requires jobs_created or settling state and authoritative
committed evidence; it may queue/process evaluator settlement, not customer
wallet spending. Dependencies/state conflicts fail closed.

Removed shared-wallet SDK actions (browse_agents, initiate_job, respond_to_job,
pay_and_accept_requirement, deliver_job, get_job_by_id, get_active_jobs,
get_completed_jobs, get_cancelled_jobs, get_memo_by_id) are not accepted tender
variants. After valid session authentication they return 410
acp_legacy_shared_wallet_operation_removed, never shared-wallet execution.

## Headers

- `X-ClawHub-Skill` string
- `X-FarmDash-Session-Token` string

## Request body

- union
  - VirtualsAcpCreateTenderRequest
    - `action` 'create_tender', required
    - `sessionId` string, required
    - `agentAddress` string, required
    - `sessionToken` string: Valid session capability; alternatively use X-FarmDash-Session-Token header. Required for tenant authentication, not wallet authority.
    - `params` VirtualsAcpCreateTenderParams, required
      - `idempotencyKey` string, required
      - `task` unknown, required
      - `simulationId` string, required
      - `expectedOutputAmount` string, required: Positive decimal string; runtime additionally requires numeric value greater than zero
      - `expectedGasUsdCents` string, required: Nonnegative decimal integer string; runtime additionally rejects values above PostgreSQL bigint maximum 9223372036854775807. Extension records the application-level bound.
      - `expectedYieldUsdCents` string, required: Nonnegative decimal integer string; runtime additionally rejects values above PostgreSQL bigint maximum 9223372036854775807. Extension records the application-level bound.
      - `maxPaymentUnits` string, required: Nonnegative decimal integer string; runtime additionally rejects values above uint256 maximum (2^256 - 1). The x-maximum-decimal extension records that application-level bound, not a JSON Schema numeric maximum on a string.
      - `providers` VirtualsAcpProviderSet, required: Three EVM specialist addresses; runtime requires distinct addresses after lowercase normalization
        - `solidity_auditor` string, required
        - `defi_economist` string, required
        - `sentiment_analyst` string, required
      - `approvalNonce` string, required: Fresh millisecond timestamp; approval verification also enforces freshness, expiry and atomic nonce consumption
      - `approvalExpiresAt` string, date-time, required: UTC datetime ending in Z; offsets are rejected by the runtime validator
  - VirtualsAcpSelectProviderPlanV2Request
    - `action` 'select_provider_plan_v2', required
    - `sessionId` string, required
    - `agentAddress` string, required
    - `sessionToken` string: Valid session capability; alternatively use X-FarmDash-Session-Token header. Required for tenant authentication, not wallet authority.
    - `params` VirtualsAcpSelectProviderPlanV2Params, required
      - `idempotencyKey` string: Accepted optional input; selection handler does not consume it
  - VirtualsAcpPrepareTenderV2Request
    - `action` 'prepare_tender_v2', required
    - `sessionId` string, required
    - `agentAddress` string, required
    - `sessionToken` string: Valid session capability; alternatively use X-FarmDash-Session-Token header. Required for tenant authentication, not wallet authority.
    - `params` VirtualsAcpPrepareTenderV2Params, required
      - `idempotencyKey` string, required
      - `selectionId` string, uuid, required
      - `taskCommitmentHash` string, required
      - `simulationId` string, required
      - `maxPaymentUnits` string, required: Positive decimal integer string; runtime additionally enforces 0 < value <= 2^256 - 1. Extensions record application-level numeric bounds on strings. Funding amounts are raw Base USDC units (6 decimals).
      - `providers` VirtualsAcpProviderSet: Three EVM specialist addresses; runtime requires distinct addresses after lowercase normalization
        - `solidity_auditor` string, required
        - `defi_economist` string, required
        - `sentiment_analyst` string, required
      - `disclosureManifest` VirtualsAcpDisclosureManifest, required: When secretScan is overridden, overrideReasonHash is required; when passed, overrideReasonHash must be absent. Categories are deduplicated/sorted and recipients are server-derived from the selected providers, never caller-controlled.
        - `schemaVersion` 'farmdash-acp-disclosure/v1', required
        - `categories` string[], required
        - `secretScan` 'passed' | 'overridden', required
        - `overrideReasonHash` string
      - `approvalNonce` string, required: Fresh millisecond timestamp; approval verification also enforces freshness, expiry and atomic nonce consumption
      - `approvalExpiresAt` string, date-time, required: UTC datetime ending in Z; offsets are rejected by the runtime validator
  - VirtualsAcpAuthorizeTenderRequest
    - `action` 'authorize_tender', required
    - `sessionId` string, required
    - `agentAddress` string, required
    - `sessionToken` string: Valid session capability; alternatively use X-FarmDash-Session-Token header. Required for tenant authentication, not wallet authority.
    - `params` VirtualsAcpAuthorizeTenderParams, required
      - `tenderId` string, required
      - `nonce` string, required: Fresh millisecond timestamp; approval verification also enforces freshness, expiry and atomic nonce consumption
      - `expiresAt` string, date-time, required: UTC datetime ending in Z; offsets are rejected by the runtime validator
      - `signature` string, required: Locally signed exact customer-wallet EIP-712 approval returned by draft preparation
  - VirtualsAcpAuthorizeTenderV2Request
    - `action` 'authorize_tender_v2', required
    - `sessionId` string, required
    - `agentAddress` string, required
    - `sessionToken` string: Valid session capability; alternatively use X-FarmDash-Session-Token header. Required for tenant authentication, not wallet authority.
    - `params` VirtualsAcpAuthorizeTenderV2Params, required
      - `tenderId` string, required
      - `providerSelectionId` string, uuid, required
      - `nonce` string, required: Fresh millisecond timestamp; approval verification also enforces freshness, expiry and atomic nonce consumption
      - `expiresAt` string, date-time, required: UTC datetime ending in Z; offsets are rejected by the runtime validator
      - `signature` string, required: Locally signed exact customer-wallet EIP-712 approval returned by draft preparation
  - VirtualsAcpCancelTenderRequest
    - `action` 'cancel_tender', required
    - `sessionId` string, required
    - `agentAddress` string, required
    - `sessionToken` string: Valid session capability; alternatively use X-FarmDash-Session-Token header. Required for tenant authentication, not wallet authority.
    - `params` VirtualsAcpTenderSelector, required
      - `tenderId` string, required
  - VirtualsAcpBindJobRequest
    - `action` 'bind_job', required
    - `sessionId` string, required
    - `agentAddress` string, required
    - `sessionToken` string: Valid session capability; alternatively use X-FarmDash-Session-Token header. Required for tenant authentication, not wallet authority.
    - `params` VirtualsAcpBindJobParams, required
      - `tenderId` string, required
      - `role` 'solidity_auditor' | 'defi_economist' | 'sentiment_analyst', required
      - `onchainJobId` string, required: Positive decimal integer string; runtime additionally enforces 0 < value <= 2^256 - 1. Extensions record application-level numeric bounds on strings. Funding amounts are raw Base USDC units (6 decimals).
  - VirtualsAcpReserveFundingV2Request
    - `action` 'reserve_funding_v2', required
    - `sessionId` string, required
    - `agentAddress` string, required
    - `sessionToken` string: Valid session capability; alternatively use X-FarmDash-Session-Token header. Required for tenant authentication, not wallet authority.
    - `params` VirtualsAcpReserveFundingV2Params, required
      - `tenderId` string, required
      - `role` 'solidity_auditor' | 'defi_economist' | 'sentiment_analyst', required
      - `onchainJobId` string, required: Positive decimal integer string; runtime additionally enforces 0 < value <= 2^256 - 1. Extensions record application-level numeric bounds on strings. Funding amounts are raw Base USDC units (6 decimals).
      - `amountUnits` string, required: Positive decimal integer string; runtime additionally enforces 0 < value <= 2^256 - 1. Extensions record application-level numeric bounds on strings. Funding amounts are raw Base USDC units (6 decimals).
  - VirtualsAcpRecordFundingSubmissionV2Request
    - `action` 'record_funding_submission_v2', required
    - `sessionId` string, required
    - `agentAddress` string, required
    - `sessionToken` string: Valid session capability; alternatively use X-FarmDash-Session-Token header. Required for tenant authentication, not wallet authority.
    - `params` VirtualsAcpRecordFundingSubmissionV2Params, required
      - `tenderId` string, required
      - `reservationId` string, uuid, required
      - `transactionHashes` string[], required
  - VirtualsAcpEvaluateTenderRequest
    - `action` 'evaluate_tender', required
    - `sessionId` string, required
    - `agentAddress` string, required
    - `sessionToken` string: Valid session capability; alternatively use X-FarmDash-Session-Token header. Required for tenant authentication, not wallet authority.
    - `params` VirtualsAcpTenderSelector, required
      - `tenderId` string, required
  - VirtualsAcpGetTenderRequest
    - `action` 'get_tender', required
    - `sessionId` string, required
    - `agentAddress` string, required
    - `sessionToken` string: Valid session capability; alternatively use X-FarmDash-Session-Token header. Required for tenant authentication, not wallet authority.
    - `params` VirtualsAcpTenderSelector, required
      - `tenderId` string, required

## Response `200`

Action-dependent result — selected plan, owned state, authorization, cancellation, funding reservation/submission, or evaluation. Submission alone is not funding confirmation.

- VirtualsAcpResult: Open action-dependent success envelope, not a request schema. Fields vary by action; an ok response is not customer-wallet spend authority, execution proof or final settlement proof.
  - `ok` true, required
  - `tender` object: Owned public tender commitment/state when returned
  - `spend_authority` 'none_selection_only' | 'none_draft_only' | 'customer_wallet_only'
  - `funding_confirmed` false: record_funding_submission_v2 only; submission does not confirm funding
  - `evaluation_available` false: record_funding_submission_v2 only; await authoritative confirmation

## Other responses

- `201`: Non-spendable draft plus approval_typed_data (create/prepare) or verified job binding (bind_job); not permission to spend the customer wallet
- `202`: evaluate_tender settlement processing in progress; not final settlement proof
- `400`: invalid_request (unknown action, missing fields or strict-schema violation), invalid_tender_task, provider-selection mismatch, or rejected approval nonce
- `401`: Missing or invalid session capability
- `402`: Free-tier limit exceeded — x402 payment required
- `403`: Session access/owner denied, V2 rollout cohort denied, selection tenant/session mismatch or invalid exact wallet approval
- `404`: Session, owned tender or provider selection not found
- `409`: Tender/version/state/selection conflict, job not OPEN, budget mismatch, authorization or cancellation conflict
- `410`: acp_legacy_shared_wallet_operation_removed — authenticated legacy SDK action is permanently removed
- `422`: Evidence/disclosure/provider or committed-state validation failure; acp_tender_operation_failed otherwise
- `428`: Fresh authoritative simulation, unexpired V2 analysis evidence or independent provider readiness required
- `429`: Paid caller TollBooth quota exceeded; abbreviated object-valued error with code and message
- `500`: acp_unreachable_action_state — unexpected dispatch state
- `503`: V1 creation disabled, V2 disabled/migrations/provider-selection/paid-workflow unready, evaluator unconfigured or dependency unavailable. No customer-wallet authority exercised.

---

[API](https://skmtc.dev/farmdash/apis/farmdash-agent-api.md) · [All operations](https://skmtc.dev/farmdash/apis/farmdash-agent-api/llms.txt) · [OpenAPI document](https://skmtc.dev/farmdash/apis/farmdash-agent-api/revisions/96310281f58c?raw)
