Skip to main content
POST
/
v1
/
sessions
POST /v1/sessions
curl --request POST \
  --url https://api.agentscore.sh/v1/sessions
This endpoint requires a paid plan ($100/mo). Free tier requests receive HTTP 402.

Overview

Verification sessions let merchants bootstrap identity for agents that don’t have a wallet or operator credential. When an agent tries to perform a gated action without identity, the merchant creates a session and returns the verification URL to the agent. The session returns two secrets:
  • session_id — goes in the verification URL (user-facing)
  • poll_secret — given to the agent for polling (never in URLs)

Request

Headers

HeaderRequiredDescription
X-API-KeyYesYour API key (paid or enterprise tier)
Content-TypeYesapplication/json

Body

{
  "context": "wine_purchase",
  "product_name": "2022 Martin Estate Rose"
}
FieldTypeRequiredDescription
contextstringNoFreeform context label (e.g., “wine_purchase”)
product_namestringNoProduct name shown during verification (max 200 chars)
The merchant name shown on the verify page is derived from your account’s merchant name (set in dashboard Settings), not from the request. Verification is agent-driven: after the user completes KYC they close the tab, and the requesting agent retrieves the credential by polling GET /v1/sessions/:token. There is no browser redirect back to the merchant — this API does not accept return_url or any payment-method metadata.

Response

{
  "session_id": "sess_abc123...",
  "poll_secret": "poll_xyz789...",
  "verify_url": "https://agentscore.sh/verify?session=sess_abc123...",
  "poll_url": "https://api.agentscore.sh/v1/sessions/sess_abc123...",
  "expires_at": "2026-04-09T13:00:00Z"
}
Sessions expire after 1 hour.

Polling

GET /v1/sessions/{session_id}
X-Poll-Secret: poll_xyz789...
StatusMeaning
pendingUser hasn’t completed verification yet
verifiedUser verified — operator_token included in response
consumedToken already issued to a previous poll
expiredSession expired (1 hour TTL)
failedStripe Identity verification did not succeed (unreadable ID, selfie mismatch, etc.)
flaggedIdentity verified but sanctions screening flagged a potential match — credential issuance is blocked pending manual review

Poll response by status

Pending — user hasn’t completed verification yet:
{
  "session_id": "sess_abc123...",
  "status": "pending",
  "retry_after_seconds": 5,
  "next_steps": {
    "action": "continue_polling",
    "poll_interval_seconds": 5,
    "eta_message": "Users typically complete identity verification in 2-5 minutes. Continue polling every 5 seconds until status becomes verified, consumed, or expired."
  }
}
Verified — user verified, one-time operator_token included:
{
  "session_id": "sess_abc123...",
  "status": "verified",
  "operator_token": "opc_newtoken...",
  "completed_at": "2026-04-09T12:30:00Z",
  "token_ttl_seconds": 86400,
  "next_steps": {
    "action": "retry_merchant_request_with_operator_token",
    "header_name": "X-Operator-Token",
    "user_message": "Verification complete. Retry the original merchant request with X-Operator-Token set to the operator_token value."
  }
}
The token is returned exactly once. Subsequent polls return consumed without the token. Consumed — token already issued to a previous poll:
{
  "session_id": "sess_abc123...",
  "status": "consumed",
  "next_steps": {
    "action": "use_stored_operator_token",
    "user_message": "The operator_token was already delivered on a previous poll. If you did not save it, ask the merchant to create a new session."
  }
}
Expired — session expired (1 hour TTL):
{
  "session_id": "sess_abc123...",
  "status": "expired",
  "next_steps": {
    "action": "create_new_session",
    "user_message": "This verification session has expired."
  }
}
Failed — Stripe Identity verification did not succeed:
{
  "session_id": "sess_abc123...",
  "status": "failed",
  "next_steps": {
    "action": "verification_failed",
    "user_message": "Identity verification was not successful. The user may need to try again with a clearer photo or different ID. Create a new purchase to start a fresh verification session."
  }
}
Flagged — identity verified but sanctions screening flagged a potential match. The user must contact support before a credential can be issued:
{
  "session_id": "sess_abc123...",
  "status": "flagged",
  "next_steps": {
    "action": "contact_support",
    "support_email": "support@agentscore.sh",
    "support_subject": "Sanctions screening dispute",
    "user_message": "Identity was verified, but sanctions screening flagged a potential match. Credentials cannot be issued automatically. If you believe this is in error, contact support@agentscore.sh to dispute."
  }
}

Poll response fields

FieldTypeWhen presentDescription
next_stepsobjectAlwaysAction guidance that varies by status
retry_after_secondsnumberpendingRecommended poll interval in seconds
token_ttl_secondsnumberverifiedTTL of the issued operator token in seconds

Rate limits

The poll endpoint is rate-limited to 30 requests per minute per IP. Responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers.