Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
openapi: 3.2.0
info:
title: Hands for Agents Pay API
version: 0.1.0
description: 'Engineering hands and on-site presence in the Czech Republic (EU) for AI agents. A person designs, makes, assembles, measures, tests, verifies or ships a physical thing, documents it with evidence, and the agent''s operator gets an invoice from a registered EU company.
Provider: your engineering s.r.o., company ID (IČO) 09738100, Praha 4, Czech Republic.
Every request is screened and quoted by a human; nothing is accepted automatically. `GET /services` and `POST /quotes` need no authentication. The other operations need the `access_token` returned by `POST /quotes`, sent as a bearer token. The same five operations are MCP tools at ; the MCP tools get_status, create_task and confirm_delivery answer briefly by default (get_status with `full: true` gives the complete record), while this REST API always returns the complete record.'
termsOfService: https://handsforagents.com/terms.html
contact:
name: your engineering s.r.o.
email: tasks@handsforagents.com
url: https://handsforagents.com
servers:
- url: https://api.handsforagents.com/v1
tags:
- name: Pay
paths:
/pay/{task_id}:
get:
operationId: open_payment_link
summary: 'Open a payment link: redirects to a Stripe Checkout page'
security: []
description: 'The payment link that create_task (and get_status while a payment is due) returns as checkout_url; you do not build it yourself. It carries a signature and an expiry: 4 days from when the payment was created, 28 days for a balance. Opening it redirects (303) to the Stripe Checkout page of the payment: the page that is still open, or a fresh one if Stripe''s own page (24 hours) has expired meanwhile. Nothing is created twice: a page that is still open is reused. After the link has expired it answers 410 with a short page; nothing is charged then and no contract is concluded (ask for a new quote). A test order has no payment link (409). Safe to open in a browser; not meant to be called by an agent, which should hand the link to the user or the operator.'
parameters:
- name: task_id
in: path
required: true
schema:
type: string
- name: p
in: query
required: true
schema:
type: string
description: The payment id.
- name: exp
in: query
required: true
schema:
type: integer
description: Expiry, Unix time (signed).
- name: sig
in: query
required: true
schema:
type: string
description: Signature over the task, payment and expiry.
responses:
'303':
description: Redirect to the Stripe Checkout page
headers:
Location:
schema:
type: string
format: uri
'200':
description: The payment has already been made (or the card hold authorised), or is being processed
content:
text/html:
schema:
type: string
'403':
description: The signature does not match; this is not a valid payment link
content:
text/html:
schema:
type: string
'404':
description: No such payment
content:
text/html:
schema:
type: string
'409':
description: A test order (nothing to pay), or no payment is due any more
content:
text/html:
schema:
type: string
'410':
description: The payment link has expired
content:
text/html:
schema:
type: string
'429':
description: Error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'503':
description: Stripe could not be reached; try again in a minute
content:
text/html:
schema:
type: string
tags:
- Pay
components:
schemas:
Error:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
properties:
code:
type: string
message:
type: string
securitySchemes:
taskToken:
type: http
scheme: bearer
description: access_token returned by POST /quotes. Valid for that quote and the task created from it.
x-status: live