DocsDocs
Open app

Headless Signup

Agent-directed browser-backed account creation with 6 MCP tools.

The signup flow lets an agent coordinate Doow account creation while sensitive identity operations (OAuth, password) remain in secure browser handoffs.

Agent

Begin signup and poll for status changes.

Initiates flow and monitors user's progress

Browser

Sign in with Google, Microsoft, or Zoho.

User completes OAuth and profile form

Server

Create session and issue tokens.

Signup completes and session is established

MCP Tokens

Claim tokens for onboarding.

Agent can now call onboarding tools

Endpoint

text
POST https://mcp.doow.co/mcp/signup

Authentication

The signup flow uses a flow capability token:

ToolAuth
signup_beginNone (unauthenticated)
All other signup toolsAuthorization: Flow hs_cap_...

The flow capability is returned by signup_begin and must be included in all subsequent requests.

Tools

ToolTypeDescription
signup_beginmutationStart browser-backed signup flow
signup_statusqueryPoll flow status
signup_save_profilemutationSave allowlisted profile draft
signup_open_handoffmutationIssue next browser handoff
signup_join_requestmutationSubmit join request for existing org
signup_claim_tokensmutationClaim MCP tokens (one-time per flow)

Flow statuses

StatusMeaningAgent action
WAITING_FOR_OAUTHUser is in the browser choosing their SSO providerWait and guide user to complete sign-in
OAUTH_VERIFIEDUser signed in with SSO and can complete their profileCall signup_open_handoff to issue the completion handoff
JOIN_REQUEST_REQUIREDUser's email domain matches an existing organizationCall signup_join_request to request access
WAITING_FOR_ADMINJoin request sent and awaiting admin approvalWait for admin to approve
WAITING_FOR_BROWSERFlow is waiting on the browser stepWait for the browser step to finish
COMPLETEDSignup finished and session is establishedCall signup_claim_tokens to get MCP tokens
FAILEDFlow failed due to an errorShow error and offer to restart
EXPIREDFlow timed out before completionStart a new flow with signup_begin

WAITING_FOR_BROWSER belongs to the declared status set, but the current server keeps a flow that waits on the browser at OAUTH_VERIFIED with next_action set to OPEN_COMPLETE_SIGNUP, so you may not observe it yet. Treat it as a wait if it appears.

Step 1: Begin flow

Call signup_begin to start a new signup flow. This is the only unauthenticated call.

json
{"jsonrpc": "2.0","id": 1,"method": "tools/call","params": {  "name": "signup_begin",  "arguments": {    "email_hint": "user@example.com",    "company_hint": "Acme Inc"  }}}

Response:

json
{"flow_id": "signup_abc123","flow_capability": "hs_cap_xyz789","handoff_url": "https://app.doow.co/signup#headless_handoff=hs_handoff_...","expires_at": "2026-09-21T14:00:00Z"}

Save flow_id and flow_capability for subsequent calls.

Step 2: Open browser handoff

Direct the user to handoff_url. The agent should open this automatically:

bash
# macOSopen "https://app.doow.co/signup#headless_handoff=hs_handoff_..."# Linuxxdg-open "https://app.doow.co/signup#headless_handoff=hs_handoff_..."# Windowsstart "https://app.doow.co/signup#headless_handoff=hs_handoff_..."

Step 3: Poll status

Poll signup_status every 2-3 seconds to track progress:

json
{"jsonrpc": "2.0","id": 2,"method": "tools/call","params": {  "name": "signup_status",  "arguments": {    "flow_id": "signup_abc123"  }}}

Include the flow capability header:

bash
curl -X POST https://mcp.doow.co/mcp/signup \-H "Authorization: Flow hs_cap_xyz789" \-H "Content-Type: application/json" \-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"signup_status","arguments":{"flow_id":"signup_abc123"}}}'

Response:

json
{"flow_id": "signup_abc123","status": "WAITING_FOR_OAUTH","next_action": "OPEN_OAUTH","organization_state": null,"email_masked": null}

Step 4: Handle status transitions

The agent should respond to each status:

StatusAgent behavior
WAITING_FOR_OAUTH"Select a sign-in provider to continue..."
OAUTH_VERIFIEDOptionally call signup_save_profile, then signup_open_handoff for "Complete password and terms..."
JOIN_REQUEST_REQUIREDAsk user, then call signup_join_request
WAITING_FOR_ADMIN"Waiting for admin approval..."
WAITING_FOR_BROWSER"Finish the browser step to continue..."
COMPLETED"Signup complete!" then call signup_claim_tokens
FAILEDShow error, offer to restart
EXPIRED"Session expired." then call signup_begin

Save profile (optional)

If the agent has profile data, it can pre-fill via signup_save_profile:

json
{"jsonrpc": "2.0","id": 3,"method": "tools/call","params": {  "name": "signup_save_profile",  "arguments": {    "flow_id": "signup_abc123",    "first_name": "Jane",    "last_name": "Smith",    "business_name": "Acme Inc",    "work_place_role": "Finance Manager",    "country_of_incorporation": "US",    "default_spending_currency": "USD"  }}}

Join existing organization

If JOIN_REQUEST_REQUIRED, the user's email domain matches an existing org:

json
{"jsonrpc": "2.0","id": 4,"method": "tools/call","params": {  "name": "signup_join_request",  "arguments": {    "flow_id": "signup_abc123",    "message": "Hi, I'd like to join the team."  }}}

After submission, status transitions to WAITING_FOR_ADMIN until an org admin approves.

Issue completion handoff

When status is OAUTH_VERIFIED (with next_action: "OPEN_COMPLETE_SIGNUP"), the user needs to complete password and terms in the browser. Call signup_open_handoff to issue the completion URL:

json
{"jsonrpc": "2.0","id": 4,"method": "tools/call","params": {  "name": "signup_open_handoff",  "arguments": {    "flow_id": "signup_abc123"  }}}

Response:

json
{"handoff_url": "https://app.doow.co/complete-signup#headless_handoff=hs_handoff_...","expires_at": "2026-09-21T14:30:00Z"}

Open this URL for the user to complete password setup and accept terms. Poll signup_status until COMPLETED.

Step 5: Claim MCP tokens

When status: "COMPLETED" and next_action: "OPEN_ONBOARDING", claim tokens:

json
{"jsonrpc": "2.0","id": 5,"method": "tools/call","params": {  "name": "signup_claim_tokens",  "arguments": {    "flow_id": "signup_abc123"  }}}

Response:

json
{"mcp_access_token": "eyJ...","mcp_refresh_token": "mcp_rt_...","flow_id": "signup_abc123"}

Step 6: Continue to onboarding

Use the claimed MCP token to authenticate onboarding requests:

bash
curl -X POST https://mcp.doow.co/mcp/onboarding \-H "Authorization: Bearer eyJ..." \-H "Content-Type: application/json" \-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"onboarding_status","arguments":{}}}'

See Headless Onboarding for the complete onboarding flow.

Tool reference

  1. signup_begin — Start a new browser-backed signup flow.

    FieldTypeRequiredDescription
    email_hintstringNoPre-fill email field
    company_hintstringNoPre-fill company field

    Returns: flow_id, flow_capability, handoff_url, status, expires_at

  2. signup_status — Check the current flow status.

    FieldTypeRequiredDescription
    flow_idstringYesThe flow ID from signup_begin

    Returns: flow_id, status, next_action, email_masked, organization_state, profile, error_code

    signup_status does not return expires_at; read the expiry from signup_begin or signup_open_handoff. error_code is present only when status is FAILED, and organization_state only once the flow is routed to an organization.

  3. signup_save_profile — Save allowlisted profile fields.

    FieldTypeRequiredDescription
    flow_idstringYesThe flow ID
    first_namestringNoUser's first name
    last_namestringNoUser's last name
    business_namestringNoCompany name
    work_place_rolestringNoUser's role
    country_of_incorporationstringNoISO country code
    default_spending_currencystringNoISO currency code
    financial_year_startstringNoMonth (e.g. "January")
    inactivity_periodintegerNoDays
  4. signup_open_handoff — Issue a new browser handoff URL.

    FieldTypeRequiredDescription
    flow_idstringYesThe flow ID

    Returns: handoff_url, expires_at

    Only valid while the flow is OAUTH_VERIFIED.

  5. signup_join_request — Submit a request to join an existing organization.

    FieldTypeRequiredDescription
    flow_idstringYesThe flow ID
    messagestringNoMessage to org admin
  6. signup_claim_tokens — Claim MCP tokens for onboarding (one-time per flow).

    FieldTypeRequiredDescription
    flow_idstringYesThe flow ID

    Returns: mcp_access_token, mcp_refresh_token, flow_id

Was this page helpful?