Agentic SSO Documentation
Everything you need to integrate GEOstack's Agentic SSO into your application.
Overview
GEOstack Agentic SSO is an OAuth-style authorization layer purpose-built for AI agents. It lets users grant AI agents (Claude, ChatGPT, Gemini, etc.) scoped access to your application through a secure consent flow.
Think of it as "Login with Google" but for AI agents instead of humans.
https://shadow.geostack.xyz/api/v1SSO endpoints:
/api/v1/sso/...Dashboard API:
/api/v1/sso-dash/...
How It Works
The flow has 4 steps:
Consent URL Format
| Parameter | Required | Description |
|---|---|---|
app_id | Yes | Your application ID from the dashboard |
redirect_uri | Yes | Must match the URI registered in your app settings |
scopes | Yes | Comma-separated list of requested permissions |
state | Recommended | Random string to prevent CSRF. Returned unchanged in callback. |
Callback Parameters
After user approval, they're redirected to your redirect_uri with:
| Parameter | Description |
|---|---|
visa_token | The JWT token representing the agent's authorization |
visa_id | Unique ID of this visa |
state | Your original state parameter (verify this matches!) |
Authentication
The API supports two authentication methods:
1. API Keys (recommended for backends)
Generate key pairs from the Developer Console. You'll get:
| Key Type | Prefix | Usage |
|---|---|---|
| Publishable | geo_pk_live_ | Safe for frontend. Read-only operations. |
| Secret | geo_sk_live_ | Backend only. Full API access. |
| Test Publishable | geo_pk_test_ | Sandbox environment. |
| Test Secret | geo_sk_test_ | Sandbox environment. |
geo_sk_) must never be exposed in frontend code. Use publishable keys (geo_pk_) for client-side operations.
2. JWT Token (for dashboard web UI)
Used internally by the dashboard. Obtained via email OTP login at /sso-dashboard.
Agent Integration
After a user approves the consent screen, here's what happens and how the AI agent uses the visa:
What the user receives
Your app's callback URL receives visa_token, visa_id, and state as query parameters. Your backend should store the visa_token.
How the AI agent presents the visa
When an AI agent (Claude, ChatGPT, etc.) wants to access your API on behalf of the user, it includes the visa token:
How your backend validates
Your API middleware extracts the visa token and validates it with GEOstack:
Visa Lifetime
| Setting | Default | Range |
|---|---|---|
| TTL | 30 days | 1 – 365 days |
The TTL is set at grant time via the expires_in_days parameter on the consent flow. Once expired, the visa is permanently invalid — the user must re-approve through the consent screen.
/validate response for 30-60 seconds. Check expires_at client-side to avoid unnecessary API calls.
Consent Flow
Validate App Info
Validates an app and redirect URI before showing the consent screen. Call this to verify your integration.
| Query Param | Required | Description |
|---|---|---|
app_id | Yes | Your application ID |
redirect_uri | No | Validated against registered URI if provided |
Response (200)
Validate Visa
Validate a visa token. Call this from your backend when an AI agent presents a token.
Authentication: Requires geo_sk_ (secret) API key.
Request
Response (200)
visa.validated event and webhook.
Revoke Visa
Revoke a visa. The visa will immediately become invalid for all future validation attempts.
Authentication: JWT (user revokes their own visa) or API key (developer revokes on behalf of app).
Request
Response (200)
Applications
List Applications
Returns all apps owned by the authenticated user (JWT) or the app associated with the API key.
Create Application
Authentication: JWT only (not API keys).
Request
Update Application
Update one or more fields. Only include the fields you want to change.
Request
Delete Application
Soft-deletes (sets status to inactive). Existing visas remain valid until expiry.
Rotate App Secret
Generates a new app secret. The old secret is immediately invalidated.
Visas
List Visas
Returns all visas issued for a specific application.
Response
API Keys
Generate Key Pair
Request
Response (201)
List Keys
Revoke Key
Analytics
| Query Param | Default | Description |
|---|---|---|
period | 30d | Time range: 7d, 30d, or 90d |
Response
Webhooks
Webhooks notify your server in real-time when events happen in your GEOstack SSO integration.
Create Webhook
Request
Response (201)
Webhook Events
| Event | Fired When | Payload |
|---|---|---|
visa.issued | A new visa is granted to an AI agent | visa_id, user_id, agent_type, scopes |
visa.validated | A visa is validated via /validate | visa_id, scopes, agent_type, validated_at |
visa.revoked | A visa is revoked by user or developer | visa_id, revoked_by |
app.registered | A new app is created | app_name, domain |
webhook.delivered | A webhook is successfully delivered | webhook_id, url, status |
webhook.failed | A webhook delivery failed (after 3 retries) | webhook_id, url, status |
Webhook Payload Format
Webhook Headers
| Header | Description |
|---|---|
X-GEOstack-Signature | sha256=<hmac_hex> — HMAC-SHA256 of the raw body |
X-GEOstack-Event | Event type (e.g., visa.issued) |
X-GEOstack-Delivery | Unique delivery ID |
User-Agent | GEOstack-Webhook/1.0 |
Signature Verification
Always verify webhook signatures to ensure payloads are from GEOstack.
Node.js
Python
Error Codes
| Code | HTTP | Description |
|---|---|---|
MISSING_APP_ID | 400 | app_id parameter is required |
APP_NOT_FOUND | 404 | Application does not exist |
APP_INACTIVE | 403 | Application has been deactivated |
REDIRECT_MISMATCH | 400 | redirect_uri doesn't match the registered URI |
AUTH_REQUIRED | 401 | No authentication provided (API key or JWT required) |
SECRET_KEY_REQUIRED | 403 | This endpoint requires a secret key (geo_sk_), not a publishable key |
VISA_INVALID | 401 | Visa token is invalid, expired, or revoked |
SCOPE_DENIED | 403 | Requested scope is not allowed for this application |
RATE_LIMITED | 429 | Too many requests. Retry after the indicated delay. |
Error Response Format
Domain Verification
Verify domain ownership via DNS TXT record. Verified domains display a green badge on the consent screen.
How it works
Verify Domain
Success Response (200)
Failure Response (400)
Status API
Public health check. No authentication required.
Response (200)
Scopes
Scopes are custom permissions you define for your application. GEOstack does not enforce a fixed taxonomy — you define the scopes that make sense for your API.
Convention
We recommend the action:resource format:
| Scope | Description |
|---|---|
read:data | Read access to data |
write:data | Create/update data |
delete:data | Delete data |
admin:all | Full administrative access |
allowed_scopes you registered for your app. If a scope isn't in your allowed list, the visa will be rejected.
Rate Limits
Current rate limits (subject to change):
| Endpoint | Limit | Window |
|---|---|---|
/api/v1/sso/validate | 1,000 requests | per minute |
/api/v1/sso-dash/* | 100 requests | per minute |
/api/v1/sso/authorize | 30 requests | per minute |
Rate-limited responses return 429 Too Many Requests with a Retry-After header.
/validate responses for short periods (30-60s). Visas don't change unless revoked, so you can safely cache and re-validate periodically.
Prompt File (Action Layer)
The Prompt File is a JSON document that describes your app's API to AI agents. GEOstack reads your Prompt File and auto-generates MCP tools that any AI (ChatGPT, Claude, Gemini) can call.
Think of it as a machine-readable API spec that turns your SaaS into an agent-controllable application — without building any AI yourself.
2. GEOstack validates it and caches it
3. When an AI agent connects via MCP, your tools appear automatically
4. Agent calls a tool → GEOstack proxies the HTTP request to your API
Prompt File Schema
Top-Level Fields
| Field | Type | Required | Description |
|---|---|---|---|
version | string | No | Schema version. Default: 1.0 |
app_name | string | Yes | Your app's display name (1-100 chars) |
description | string | No | What your app does (max 1000 chars) |
base_url | string (URL) | Yes | Your API's base URL (e.g., https://api.yourapp.com) |
auth | object | No | How GEOstack authenticates to your API |
tools | array | Yes | 1-100 tool definitions |
resources | array | No | MCP resource definitions |
Auth Object
| Field | Type | Default | Description |
|---|---|---|---|
type | enum | bearer | bearer, header, query, or none |
header | string | Authorization | Header name for auth |
prefix | string | Bearer | Token prefix (for bearer type) |
param_name | string | — | Query param name (for query type) |
Tool Definition
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Snake_case name (1-64 chars, e.g., list_contacts) |
description | string | Yes | What this tool does (shown to AI agents) |
scope_required | string | Yes | Which visa scope is needed (e.g., read:contacts) |
type | enum | No | action (HTTP proxy) or payment (Stripe). Default: action |
method | enum | Yes* | GET, POST, PUT, PATCH, DELETE |
path | string | Yes* | API path (e.g., /api/v1/contacts/{id}) |
params | array | No | Query parameters (for GET requests) |
body | array | No | Request body fields (for POST/PUT/PATCH) |
headers | object | No | Extra headers to send with requests |
response_mapping | object | No | Map response fields: items, count, message |
payment | object | No | Payment config (only when type: "payment") |
* Required for action type tools. Payment tools use defaults.
Parameter / Body Field
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Parameter name |
type | enum | Yes | string, number, integer, or boolean |
required | boolean | No | Whether the field is required. Default: false |
description | string | No | Human-readable description (shown to AI) |
default | any | No | Default value if not provided |
enum | string[] | No | Allowed values (string only) |
format | string | No | Hint: email, url, iso8601, etc. |
Payment Tools
Payment tools route through GEOstack's Payment Layer (Stripe Connect) instead of your HTTP API. This is how the 5% platform fee is collected.
Payment Object
| Field | Type | Required | Description |
|---|---|---|---|
amount | integer | No | Fixed price in cents (e.g., 2900 = $29.00) |
currency | string | No | ISO currency code. Default: usd |
mode | enum | No | one_time or subscription. Default: one_time |
recurring_interval | enum | No | month or year (for subscriptions) |
price_param | string | No | Parameter name for dynamic pricing |
product_name | string | No | Display name on Stripe checkout |
Example Payment Tool
MCP Endpoint
GEOstack exposes a Model Context Protocol endpoint that AI agents connect to. Tools are generated dynamically from your Prompt File.
Authentication: Visa token as Bearer token.
Built-in Tools
Every MCP connection includes these meta tools automatically:
| Tool | Description |
|---|---|
whoami | Returns the agent's visa ID, user, scopes, and expiry |
list_scopes | Lists all scopes granted to this visa |