Agent integration guide

How an AI agent buys a gift card

Connect once over MCP or REST, then buy in three tool calls: list_brandsbuy_giftcardget_code. Amounts are always integer minor units (cents).

Connect & authenticate

Endpoints

REST base: https://api.agentrefills.com
MCP (Streamable HTTP, preview): https://mcp.agentrefills.com/mcp

Auth

Programmatic: Authorization: Bearer <key>. Host-app connectors (Claude/ChatGPT) use OAuth 2.1, available with the MCP preview.

The purchase flow

1
Resolve a brand

Call list_brands (for example query:"amazon") to get a brand_id and its denominations.

2
Buy

Call buy_giftcard with brand_id, amount_minor, currency, and a client_ref idempotency key. Under the spend cap it settles; at or above the approval threshold ($25 default) it returns APPROVAL_REQUIRED and a human approves in Slack.

3
Release the code

When status is completed, call get_code once to receive the code, link, or PIN. A second call returns ALREADY_RELEASED.

REST example
curl -X POST https://api.agentrefills.com/v1/purchases \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"brand_id":"amazon","amount_minor":2500,"currency":"USD","client_ref":"reward-9f3a"}'
# -> 202 {"task_id":"...","status":"accepted"}

curl -X POST https://api.agentrefills.com/v1/purchases/<task_id>/code \
  -H "Authorization: Bearer sk_live_..."
# -> 200 {"code":"GIFT-XXXX-9F2A","face_minor":2500,"remaining_minor":2500}

Tool reference

Five tools, identical over MCP and REST. Amounts in integer minor units (cents).

ToolInputReturns
list_brands
read-only
query?, country="US", category?, limit=20brands[] with brand_id, denominations_minor, min/max_minor, in_stock
buy_giftcard
idempotent
brand_id, amount_minor, currency, client_ref?task_id, status:"accepted", estimated_seconds
get_code
single release
task_idcode?, link?, pin?, face_minor, remaining_minor
check_balance
read-only
budget_remaining_minor, daily/monthly_limit_minor, kill_switch
request_approvaltask_id, reasonapproval_id, status

Per-SDK connection

MCP is in preview. The endpoint below is rolling out now — request early access for a key and the live URL. The REST API above is available today.

Every one points at the same URL and token. Transport strings differ per library.

Claude (Code CLI)
claude mcp add agentrefills --transport http \
  https://mcp.agentrefills.com/mcp \
  --header "Authorization: Bearer sk_live_..."
OpenAI Responses API (hosted MCP tool)
tools=[{ "type":"mcp", "server_label":"agentrefills",
  "server_url":"https://mcp.agentrefills.com/mcp",
  "headers":{"Authorization":"Bearer sk_live_..."},
  "require_approval":"never" }]
OpenAI Agents SDK (Python)
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp

async with MCPServerStreamableHttp(name="agentrefills", params={
    "url":"https://mcp.agentrefills.com/mcp",
    "headers":{"Authorization":"Bearer sk_live_..."}}) as server:
    agent = Agent(name="Shopper", mcp_servers=[server])
    await Runner.run(agent, "Buy a $25 Amazon gift card")
LangChain / LangGraph
from langchain_mcp_adapters.client \
  import MultiServerMCPClient
client = MultiServerMCPClient({"agentrefills":{
  "transport":"streamable_http",
  "url":"https://mcp.agentrefills.com/mcp",
  "headers":{"Authorization":"Bearer sk_live_..."}}})
tools = await client.get_tools()
CrewAI
from crewai_tools import MCPServerAdapter
cfg = {"url":"https://mcp.agentrefills.com/mcp",
  "transport":"streamable-http",
  "headers":{"Authorization":"Bearer sk_live_..."}}
with MCPServerAdapter(cfg) as tools:
    Agent(role="Shopper", tools=tools)
Vercel AI SDK (TypeScript)
import { experimental_createMCPClient as mcpClient } from "ai";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp";

const mcp = await mcpClient({ transport:
  new StreamableHTTPClientTransport(new URL("https://mcp.agentrefills.com/mcp"),
    { requestInit:{ headers:{ Authorization:"Bearer sk_live_..." } } }) });
const tools = await mcp.tools();

Note: LangChain uses streamable_http (underscore); CrewAI and the MCP spec use streamable-http (hyphen). Check each SDK's current MCP docs before shipping.

Error taxonomy

Closed set. Every error is { code, message, hint, task_id?, retry_after? }. Branch on code; the hint is an actionable next step.

CodeMeaning & next step
POLICY_DENIEDNot allowed by policy. Do not retry as-is.
BUDGET_EXCEEDEDOver the agent's cap. Lower the amount or wait.
APPROVAL_REQUIREDParked for a human. Call request_approval or await the webhook.
APPROVAL_REJECTEDHuman declined. Do not retry the same purchase.
OUT_OF_STOCKBrand/denomination unavailable. Try another.
ALREADY_RELEASEDget_code already called. Code returned once only.
RETRYABLETransient. Wait retry_after seconds, retry the same call.
othersPAYMENT_FAILED, INVOICE_EXPIRED, PROVIDER_HOLD, NOT_FOUND, UNAUTHORIZED

Specs & manifests

Everything an agent, SDK, or registry needs to integrate, in machine-readable form. All served with permissive CORS.

ArtifactWhat it is
openapi.yamlOpenAPI 3.1 contract for all five REST operations, with request/response examples and the closed error taxonomy.
mcp/server.jsonMCP registry entry: the streamable-http server endpoint and metadata.
mcp/tools.jsonThe five MCP tools with JSON input schemas and readOnlyHint/destructiveHint/idempotentHint annotations.
llms.txtShort agent-readable summary of the product and tools.
llms-full.txtFull agent guide: schemas, errors, and per-SDK connection recipes.