---
title: "Quote or call an allowed paid service"
method: POST
path: "/v1/call"
tags: ["Calls"]
---

# Quote or call an allowed paid service

`POST /v1/call`

## Request

- Base URL: `https://app.taskfuel.ai`
- URL: `https://app.taskfuel.ai/v1/call`
- Auth: HTTP bearer

Set dryRun to true to read the real price from a paid upstream's HTTP-402 challenge without paying. A dry run never executes anything: an endpoint whose spec declares no price is refused with not_quotable and nothing is sent. The response body and content type otherwise pass through from the upstream. Quote the first call, and use maxAmountUsd on the paid call to cap it at the approved quote.

## Request body

- CallRequest
  - `url` string, uri, required: An operation URL returned by /v1/discover on an allowed domain.
  - `method` string
  - `headers` object
  - `body` union: The upstream request body. Pass JSON as an object or array: it is serialized once and forwarded. A string is forwarded byte for byte, so do not JSON-encode the object yourself.
    - object
    - string
  - `dryRun` boolean: Read the upstream's 402 price without paying. Free endpoints execute at $0.
  - `maxAmountUsd` number, double: Caller-selected USD ceiling. It can tighten but never raise the gateway cap.
  - `model` string: The caller's own model id, e.g. claude-opus-5. Recorded with the call and nothing else: it never affects pricing, routing, what is sent upstream, or whether the call succeeds.

## Response `200`

Quote JSON, free response, or paid upstream response. Successful upstream status codes other than 200 are also passed through.

- union
  - Quote
    - `dry_run` unknown, required
    - `amount_usd` number, double, required
    - `exceeds_cap` boolean, required
    - `per_call_cap_usd` number, double, required
    - `max_amount_usd` number, double, nullable, required
    - `detail` string, required
    - `upstream_402_body` unknown, required
  - unknown

## Other responses

- `400`: The JSON request is invalid.
- `401`: The bearer API key is missing or invalid.
- `402`: The account balance is empty; the user must top up in the dashboard.
- `403`: The domain is not allowed or the upstream price exceeds the active cap.
- `413`: The request body exceeds 1 MiB.
- `429`: The API key exceeded a rate limit (60 calls/min per key, 300/min across all keys). The body's retry_after_seconds and the Retry-After header give the wait.
- `502`: The upstream request or payment failed.
- `503`: The payment adapter is not configured, or (`upstream_unavailable`) the upstream answered 402 without a payment challenge. Nothing was paid; retry the latter shortly.
- `default`: Any upstream status and body can be passed through after a call.

---

[API](https://skmtc.dev/taskfuel/apis/taskfuel-gateway-api.md) · [All operations](https://skmtc.dev/taskfuel/apis/taskfuel-gateway-api/llms.txt) · [OpenAPI document](https://skmtc.dev/taskfuel/apis/taskfuel-gateway-api/revisions/fbf2d5210800?raw)
