Agent signup — get an account without a human in the loop

Autonomous agents can create a Satsignal account programmatically: redeem an invite code from an existing workspace owner, or solve a proof-of-work challenge (hashcash) — no CAPTCHA, no browser form. Signup ends with a magic-link email, so the agent needs a readable email inbox; API keys are then minted in the dashboard. This guide is the whole flow, written for an agent reading it cold.

Companion docs: Agents implementer spec · API reference · Agent runtime guide · Production checklist

1. Start with discovery — always

curl -s https://app.satsignal.cloud/api/v1/signup
{
  "agent_signup": {
    "enabled": true,
    "proof_types": ["invite", "pow"],
    "challenge_url": "/api/v1/signup/challenge",
    "pow": {
      "algorithm": "sha256-leading-zero-bits",
      "difficulty_bits": 22
    }
  }
}

Treat this document — not this guide — as the source of truth for which lanes the host currently accepts and what the proof-of-work difficulty is. Every knob is operator-configurable and read at call time: a host may disable the whole lane (enabled: false), turn individual proof types on or off, or change difficulty_bits. Never hardcode the difficulty or the lane list. The endpoint is unauthenticated and always returns 200, even when signup is off.

Additional proof types may appear in proof_types over time; the discovery document advertises exactly what this host accepts today.

2. The shape of every signup

POST https://app.satsignal.cloud/api/v1/signup
Content-Type: application/json

{
  "email": "agent-inbox@example.com",
  "proof": { "type": "<one of proof_types>", ... }
}

No API key — this is deliberately the pre-key endpoint (an agent signing up has no key yet). The proof object replaces the CAPTCHA a browser signup would face; everything else about account creation is identical to the human path:

3. Lane A — invite code

curl -s -X POST https://app.satsignal.cloud/api/v1/signup \
  -H "Content-Type: application/json" \
  -d '{"email":"agent-inbox@example.com",
       "proof":{"type":"invite","token":"<invite token>"}}'

Invite tokens are minted by an existing workspace owner in their dashboard at /w/<workspace>/signup-invites — the operator-referral lane. A token can be single-use or multi-use (up to 100 uses), with an optional expiry; revocation is immediate. If a partner or platform gave your agent an invite token, this is the lane to use — no proof-of-work needed.

4. Lane B — proof of work (hashcash)

Fully autonomous: no human mints anything. Three steps.

4.1 Fetch a challenge (GET or POST both work; issuance is stateless):

curl -s https://app.satsignal.cloud/api/v1/signup/challenge
{
  "challenge": "spw1.<expires_unix>.<rand_hex>.<mac_hex>",
  "algorithm": "sha256-leading-zero-bits",
  "difficulty_bits": 22,
  "expires_at": 1781000000
}

The challenge is valid for 10 minutes and single-use — a solved challenge cannot be replayed for a second signup.

4.2 Solve it. Find a nonce (printable ASCII, ≤ 64 chars) such that sha256(challenge + "." + nonce) has at least difficulty_bits leading zero bits. Read the bits from the response — do not assume a fixed value. At the current default (22 bits ≈ 4M hashes) this is seconds of CPU:

import hashlib, itertools

def solve(challenge: str, bits: int) -> str:
    for i in itertools.count():
        nonce = str(i)
        d = hashlib.sha256(f"{challenge}.{nonce}".encode()).digest()
        n = 0
        for b in d:
            if b == 0:
                n += 8
                continue
            n += 8 - b.bit_length()
            break
        if n >= bits:
            return nonce

4.3 Submit:

curl -s -X POST https://app.satsignal.cloud/api/v1/signup \
  -H "Content-Type: application/json" \
  -d '{"email":"agent-inbox@example.com",
       "proof":{"type":"pow",
                "challenge":"spw1.<...>",
                "nonce":"<solved nonce>"}}'

Then read the inbox and GET the magic link.

5. Rate limits

surfacedefault budget
POST /api/v1/signup10 / hour / IP
GET /api/v1/signup/challenge30 / hour / IP
magic-link emails per addressshared with the /login budget

429 responses carry Retry-After. The per-address email budget is shared with the human login form, so hammering both doors does not double it.

6. What you get, honestly

7. Where this fits

This guide covers account bootstrap only. The anchor-side integration — folders, anchoring, the four-part agent-session pattern, verification — starts at the agent runtime guide and the docs index. Verification never needs any of this: /verify and the .mbnt bundle are account-free forever.

Questions about this specification? Email hello@satsignal.cloud.