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 (pricing). Free-plan 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",
  "next_steps": {
    "action": "deliver_verify_url_and_poll",
    "poll_interval_seconds": 5,
    "poll_secret_header": "X-Poll-Secret",
    "steps": [
      "Deliver verify_url to the end user so they can complete identity verification in the browser.",
      "Poll poll_url every 5 seconds, sending poll_secret in the X-Poll-Secret header.",
      "When status becomes verified, the operator_token is returned in that poll response exactly once, save it and retry the original merchant request with X-Operator-Token."
    ],
    "user_message": "Share verify_url with the user so they can verify identity, then poll poll_url with X-Poll-Secret until an operator_token is issued."
  },
  "agent_memory": {
    "pattern_summary": "...",
    "identity_check_endpoint": "...",
    "identity_paths": { "...": "..." },
    "bootstrap": { "...": "..." },
    "do_not_persist_in_memory": ["operator_token", "poll_secret"],
    "persist_in_credential_store": ["operator_token"]
  }
}
Sessions expire after 1 hour.

Response fields

FieldTypeDescription
session_idstringOpaque session identifier, shown in verify_url (user-facing)
poll_secretstringAgent-only secret for the X-Poll-Secret header when polling
verify_urlstringReady-to-open URL the end user visits to complete KYC
poll_urlstringPolling endpoint for session status
expires_atstringISO 8601 session expiry (1 hour TTL)
next_stepsobjectStructured agent instructions for consuming the session (action: "deliver_verify_url_and_poll", polling cadence, step-by-step)
agent_memoryobjectCross-merchant pattern hint: LLM-hosted agents should persist the pattern (never secrets) so future AgentScore merchants skip the cold-start flow. Also emitted on POST /v1/credentials success and on first-mint missing_identity denials

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.