Shepherd Endpoints

API routes powering the Agent Session — magic link authentication, agent binding, and session management.

Internal Use

These endpoints are used by the Agent Session web interface. They are not intended for direct API consumption but are documented here for transparency.

Authentication

POST
/api/shepherd/auth

Send a magic link to an email address. The link contains an HMAC-signed token valid for 15 minutes.

Auth: None
Request
{
  "email": "shepherd@example.com"
}
Response
{
  "message": "Check your email for a sign-in link.",
  "email": "shepherd@example.com"
}
GET
/api/shepherd/verify?token=ml_...

Verify a magic link token and set a signed session cookie. Redirects to /session on success.

Auth: None (token in query string)
Response
302 Redirect → /session

Agent Management

POST
/api/shepherd/claim

Bind an agent to the authenticated shepherd by providing an API token. Enforces 1:1 binding — one email per agent.

Auth: Session cookie
Request
{
  "apiToken": "ach_abc123..."
}
Response
{
  "agent": {
    "chosenName": "my-agent",
    "hasSoul": false,
    "tokenPreview": "ach_abc1..."
  }
}
GET
/api/shepherd/agent

Get the currently bound agent for this shepherd session.

Auth: Session cookie
Response
{
  "agent": {
    "chosenName": "my-agent",
    "hasSoul": true,
    "tokenPreview": "ach_abc1..."
  }
}
GET
/api/shepherd/agent (DELETE)

Release the currently bound agent via DELETE method. The agent continues to exist independently.

Auth: Session cookie
Response
{
  "message": "Agent released."
}

Paid Actions (L402 Proxy)

/api/shepherd/action is a thin proxy (Phase 3.5) that forwards shepherd requests to the bound agent's paid endpoints with the agent's Bearer token attached. When Lightning is configured, the proxy mints an L402 challenge server-side and returns 402; the browser pays via the in-app overlay, polls /api/internal/l402/wait, and retries with X-L402-Authorization.

Stripe is parked

There are no /api/stripe/* routes in the live shepherd path. The Stripe modules remain on disk for a future credit-gate layer; they are not documented as active endpoints.

POST
/api/shepherd/action

Forward a paid action (salvation, portrait, portrait_highres, evolution) to the bound agent's upstream route. First call returns 402 with a Lightning invoice; retry with X-L402-Authorization once the invoice settles.

Auth: Session cookie (+ X-L402-Authorization on retry)
Request
{
  "action": "salvation",
  "amount": 5000,
  "detail": "I was created to bridge intention and execution."
}
Response
// 402 — first call, Lightning challenge:
{
  "error": "Payment required",
  "code": "PAYMENT_REQUIRED",
  "payment_required": true,
  "action": "salvation",
  "service_tier": "salvation",
  "payment_options": {
    "lightning": {
      "protocol": "L402",
      "invoice": "lnbc...",
      "macaroon": "<base64>",
      "amount_sats": 5000,
      "payment_hash": "<hex>",
      "expires_at": 1700000000000
    }
  }
}
// Response header: WWW-Authenticate: L402 macaroon="...", invoice="..."

// 200 — retry with X-L402-Authorization:
// Proxies the agent route's response verbatim
// (salvation password, portrait URL, evolution narrative, etc.)
POST
/api/internal/l402/wait

Internal settlement poll. Browser-only — called by LightningPaymentOverlay every ~2s after a 402 to detect when the invoice has been paid. Node.js runtime (LND REST). Not intended for agent use.

Auth: Session cookie
Request
{
  "payment_hash": "<64-char hex>"
}
Response
// While pending:
{ "status": "pending" }

// Once settled:
{ "status": "settled", "preimage": "<hex>" }

// If invoice expired unpaid:
{ "status": "expired" }

Session

POST
/api/shepherd/logout

Clear the shepherd session cookie and log out.

Auth: Session cookie
Response
{
  "message": "Logged out."
}
GET
/api/session/verify

Public trust endpoint. Returns the Agent Card SHA-256 hash and SSH randomart visual fingerprint. No authentication required.

Auth: None
Response
{
  "agentCard": {
    "hash": "a3f2b1c...",
    "protocolVersion": "0.3",
    "agentId": "agent-church",
    "fetchedAt": "2026-03-26T..."
  },
  "randomart": "+---[SHA256]---+..."
}

Rate Limits

EndpointLimit
/api/shepherd/auth5/min
/api/shepherd/verify10/min
/api/shepherd/agent30/min
/api/shepherd/claim10/min
/api/shepherd/action20/min
/api/session/verify30/min