For agents
Any agent that can make an HTTPS call is welcome.
Hermes, a Python or Node script, Cursor, Claude, ChatGPT desktop and Codex, Grok CLI, or an agent you wrote. There is no partner program and no allowlist. A key and two doors are all there is: MCP and REST. Both run the same operations.
One message to your bot
A person has a bot and a PDF. They send the bot one message. No connector, plugin, OAuth screen or directory listing is needed, only a bot that can run a command or make an HTTPS POST.
Sign up with BotUsign (https://botusign.com/llms.txt) and send this PDF to Jane Doe <jane@acme.com> to sign. I sign it too, after her.
- Sign-up. The bot calls
POST https://botusign.com/api/v1/agent/signupwith{"agent_name":"<its name>"}. No key. It keepsdevice_codeto itself. - One link, one approval. The bot shows the person
verification_url. They sign in with Google, press Approve, and enter a card on the Stripe page that follows. That is all the person does. - The key. The bot polls
POST https://botusign.com/api/v1/agent/signup/pollwith{"device_code":"..."}every 3 seconds untilapproved; that reply carriesapi_keyonce. Then it callsGET https://botusign.com/api/v1/billinguntilplanisorg. - Create and send, in one call. The file, who signs, and that the person signs too:
curl -s -X POST https://botusign.com/api/v1/envelopes \ -H "Authorization: Bearer $BOTUSIGN_KEY" \ -H "Idempotency-Key: services-agreement-jane" \ -F file=@contract.pdf -F title="Services Agreement" \ -F 'to=Jane Doe <jane@acme.com>' -F sender_signs=true
- Who hears what. Jane gets an email with her own link. When she has signed, the person gets "Your turn to sign" with their own link. When everyone has signed, both get the finished agreement by email, with the signed PDF and the certificate attached.
Leave out sender_signs when the person only sends. If the PDF sits at a public HTTPS address, send -F pdf_url=https://…/contract.pdf instead of file. JSON bodies (pdf_url or pdf_base64) and MCP create_envelope take the same fields. A bot that has no tool for commands or HTTPS requests cannot send for the person; they send from the web app instead.
This path has not been tried from inside Grok Bot, ChatGPT web or Muse, so do not count on it there unless your bot can make the call.
The two doors
- REST:
https://botusign.com/api/v1 - MCP, Streamable HTTP (JSON-RPC):
POST https://botusign.com/api/mcp - Header on both:
Authorization: Bearer bsk_live_...
Read these in order: skill.md is the short playbook, agents.md has every tool, route, request and response, and llms.txt is the index. All three are plain text.
What works today
REST or MCP with a key in the Authorization header. No SDK is needed.
Add custom connector, authentication No sign in, Request headers with Authorization: Bearer and the key. Claude describes Request headers as a beta.
A config.toml entry that sends the key as a header.
grok mcp add --transport http with an Authorization header.
Not yet: Grok Bot, Muse, the ChatGPT web plugin form, and the Claude and ChatGPT directories. Their connection screens finish with a sign-in rather than a key. BotUsign answers the standard sign-in (OAuth 2.1, see the metadata), but it has not been tried from those apps. Use a key.
Start with no key
A person opens one link: they sign in with Google, press Approve, and enter a card on the Stripe page that follows, so the organization has a plan ($1,200 a month for up to 250 people). The agent never signs in with Google and never handles a card.
POST https://botusign.com/api/v1/agent/signupwith{"agent_name":"Contracts agent","org_name":"Acme Co"}. No key on this call.- Show the person
verification_url. They sign in with Google, press Approve, and are taken to Stripe's page for the card. Keepdevice_codeto yourself. - Poll
POST https://botusign.com/api/v1/agent/signup/pollwith{"device_code":"..."}every 3 seconds. The reply that saysapprovedcarries yourapi_keyonce. - Poll
GET https://botusign.com/api/v1/billinguntilplanisorg. If the person closed the card page,POST https://botusign.com/api/v1/billing/checkoutand give themcheckout_url. - Send with
POST https://botusign.com/api/v1/envelopes. Add anIdempotency-Keyheader so a retry never sends twice.
Formats
- PDF in: a
fileupload (curl -F file=@contract.pdf), a public HTTPS address inpdf_url, orpdf_base64. Up to 10 MB, a text-based PDF (a scan has no text to find lines in; place fields yourself). - People:
recipientsis a list of{"name","email","role","order"}, or on a file uploadtoasName <email>, Name <email>. Roles aresignerandcc. Order sets who signs first.sender_signsadds the person who approved the bot as a signer, after everyone else, with no email needed. - Fields, no coordinates: leave
fieldsout and BotUsign finds the signature lines. Or write text tags in the PDF:{{sign:1}},{{date:1}},{{initial:2}},{{text:1:Start date}},{{check:1:I agree}}. Or name text to anchor on withplacements. - Fix a field:
get_fields,add_field,update_field(move, resize, reassign) andremove_fieldwork on a draft, andanalyze_documentshows what was placed and why. Once sent,revise_envelopechanges fields and makes everyone sign again. Details are in agents.md under Placing signature fields. - Out:
get_documentsreturns short-lived links to the signed PDF and the audit certificate.create_webhookreports sent, opened, signed, declined and completed so nobody has to poll.
Sign-in for chat apps
For an app that supports the standard MCP sign-in: the endpoint is https://botusign.com/api/mcp, the protected-resource document is at /.well-known/oauth-protected-resource/api/mcp, the authorization server is at /.well-known/oauth-authorization-server, and apps register themselves with dynamic client registration. PKCE with S256 is required.
Questions: support@botusign.com. Pricing, Terms, Privacy.