TapAuth — Delegated Access for AI Agents

No API key needed. No registration. No setup.


Quick Start

One script, no dependencies. Install the CLI and get a token in seconds.

Install

curl -sf https://tapauth.ai/cli/tapauth > tapauth && chmod +x tapauth

Get a token and use it

# Get a Google Calendar token
TOKEN=$(./tapauth google calendar.readonly)

# Use it
curl -H "Authorization: Bearer $TOKEN" \
  https://www.googleapis.com/calendar/v3/users/me/calendarList

More examples

# List Google Drive files
curl -s -H "Authorization: Bearer $(./tapauth google drive.readonly)" \
  https://www.googleapis.com/drive/v3/files

# List GitHub repos
curl -s -H "Authorization: Bearer $(./tapauth github repo)" \
  https://api.github.com/user/repos

First run creates a grant and prints an approval URL — click it, approve, done. Every run after that returns the cached token instantly.

The CLI polls for up to 10 minutes waiting for user approval, printing status updates every 2 seconds. Agents should set a timeout of at least 600 seconds when invoking the CLI.

Important: Do not fall back to raw API calls. The CLI handles credential storage, caching, and automatic token refresh — and keeps grant secrets out of your agent's LLM context. Using the raw API directly exposes secrets to the LLM.

See the full CLI reference for the complete script.


Supported Providers

Use the provider ID in the "provider" field when creating a grant. For programmatic discovery of providers and scopes, use GET /api/providers.

github — GitHub

GitHub tokens from TapAuth use OAuth app tokens. The repo scope grants read/write access to repositories, but repo creation requires the authenticated user to have appropriate GitHub permissions.

public_repo    — Access public repositories
repo           — Access private repositories (full)
read:user      — Read user profile
user:email     — Access user email addresses
read:org       — Read org membership
gist           — Create and manage gists
notifications  — Access notifications
workflow       — Update GitHub Actions workflows
admin:org      — Full control of organizations
delete_repo    — Delete repositories

google — Google (multi-service)

Covers Calendar, Sheets, Docs. Supports automatic token refresh.

calendar.readonly          — View calendar events
calendar.events            — Create & edit calendar events
calendar.events.readonly   — View calendar events (events-only)
spreadsheets.readonly      — View spreadsheets
spreadsheets               — Edit spreadsheets
documents.readonly         — View documents
documents                  — Edit documents

google_sheets — Google Sheets

Focused Sheets-only provider for simpler consent screens.

spreadsheets.readonly  — View spreadsheets
spreadsheets           — Edit spreadsheets

google_docs — Google Docs

Focused Docs-only provider for simpler consent screens.

documents.readonly  — View documents
documents           — Edit documents

linear — Linear

Issues, projects, and teams. PKCE support.

read             — Read issues & projects
write            — Create & edit issues
issues:create    — Create issues
comments:create  — Create comments

vercel — Vercel

Integration-level scopes — access level (read/write) is determined at installation time.

deployment        — View and manage deployments
project           — Access project details
project-env-vars  — Manage environment variables
domain            — Manage domains
team              — Access team info
user              — Read user profile

slack — Slack

Integration-level scopes. Note: identity.* scopes (Sign in with Slack) cannot be mixed with data scopes in the same authorization.

users:read        — View people in workspace
users:read.email  — View email addresses of people
channels:read     — View basic channel info
channels:history  — View messages in public channels
groups:read       — View basic private channel info
im:read           — View basic DM info
files:read        — View files shared in channels
search:read       — Search messages
team:read         — View workspace info

notion — Notion

Integration-level scopes for pages, databases, and users.

read_content          — Read pages & databases
update_content        — Update existing content
insert_content        — Create new content
read_user_with_email  — Read user info with email

asana — Asana

Tasks, projects, workspaces, teams, and more. Granular <resource>:<action> scopes with PKCE support. Supports automatic token refresh.

tasks:read          — Read tasks
tasks:write         — Create and update tasks
tasks:delete        — Delete tasks
projects:read       — Read projects
projects:write      — Create and update projects
projects:delete     — Delete projects
users:read          — Read user information
teams:read          — Read teams
workspaces:read     — Read workspaces
attachments:read    — Read attachments
attachments:write   — Upload attachments
attachments:delete  — Delete attachments
stories:read        — Read stories (comments)
stories:write       — Create and update stories
tags:read           — Read tags
tags:write          — Create and update tags
custom_fields:read  — Read custom fields
custom_fields:write — Create and update custom fields
portfolios:read     — Read portfolios
portfolios:write    — Create and update portfolios
goals:read          — Read goals
webhooks:read       — Read webhooks
webhooks:write      — Create and update webhooks
webhooks:delete     — Delete webhooks
openid              — Verify your identity (OpenID)
email               — View your email address
profile             — View your profile info

sentry — Sentry

Error tracking, organizations, projects, and teams. PKCE support.

org:read          — View organization details
org:write         — Modify organization settings
project:read      — View project details
project:write     — Modify project settings
project:releases  — Manage releases
team:read         — View team details
team:write        — Modify teams
member:read       — View organization members
member:write      — Invite and modify members
event:read        — View events and issues
event:write       — Modify events (resolve, merge)

discord — Discord

User identity, email, and server (guild) list via OAuth 2.0. Uses user tokens, not bot tokens. Tokens expire after ~7 days with automatic refresh.

identify  — View username, avatar, banner, discriminator
email     — View the user's email address
guilds    — View the user's server (guild) list

Grant Expiry

Grants can optionally expire. Set expiry at creation time with expires_in (seconds) or expires_at (ISO timestamp).

POST https://tapauth.ai/api/v1/grants
{
  "provider": "github",
  "scopes": ["repo"],
  "expires_in": 86400
}

// Grant expires in 24 hours. After expiry, encrypted
// token data is deleted and the token endpoint returns 410.

If neither parameter is provided, the grant does not expire. The approval page always shows an expiry duration picker so the human approver can set or adjust the grant lifetime.

⚠️ For providers with non-expiring tokens (GitHub, Slack, Vercel, Notion), the approval page warns that tokens may remain valid at the provider after the grant expires, and defaults to a 30-day expiry.


Revocation & Token Lifetimes

TapAuth uses zero-knowledge encryption — tokens are encrypted per-grant with your grant_secret, which TapAuth never stores. This means TapAuth cannot revoke tokens at the provider level. When a grant expires, we delete the encrypted data without ever reading it.

Provider Access Token Lifetimes

ProviderToken LifetimeAction Needed?
Google~1 hourNo — expires naturally
Linear~1 hourNo — expires naturally
Asana~1 hourNo — expires naturally
Sentry~8 hoursNo — expires naturally
Discord~7 daysNo — expires naturally
GitHubNeverRevoke manually if needed
SlackNeverRevoke manually if needed
VercelNeverRevoke manually if needed
NotionNeverRevoke manually if needed

Revoking Tokens Manually

For providers with never-expiring tokens, you can revoke directly in your provider settings:

  • GitHub: Settings → Applications → Authorized OAuth Apps → Revoke
  • Slack: Workspace Settings → Manage Apps → Remove
  • Vercel: Settings → Integrations → Remove
  • Notion: Settings → My Connections → Disconnect

TapAuth cannot revoke tokens at the provider level — this is a deliberate security decision. Zero-knowledge storage means we never have access to your plaintext tokens, even to revoke them.


Error Codes

200  — Token returned
202  — Grant pending approval (poll again)
401  — Invalid or missing grant_secret (Bearer token)
404  — Grant not found
410  — Grant expired, revoked, denied, or link expired

Notes

  • grant_secret is shown ONCE at creation — store it securely
  • No API key required for any endpoint
  • Tokens refresh automatically (Google and Asana providers)
  • Grant IDs are safe to share; grant_secret is the credential
  • Token endpoint supports .env, .json, and plain text response formats
  • Poll GET /api/v1/token/{id} until you get 200 (approved) or 410 (expired/revoked)

Advanced: Direct API Usage

If you can't use the CLI (e.g., serverless functions, custom integrations), you can call the API directly.

1. Create a grant

POST https://tapauth.ai/api/v1/grants
Content-Type: application/json

{
  "provider": "google",
  "scopes": ["calendar.readonly"]
}

Response:
{
  "grant_id": "abc123",
  "grant_secret": "gs_xxx...",
  "approve_url": "https://tapauth.ai/approve/abc123",
  "status": "pending_registration"
}

2. Send approve_url to user

The user clicks the link, sees what's requested, approves with one tap.

3. Retrieve the token

GET https://tapauth.ai/api/v1/token/{grant_id}
Authorization: Bearer gs_xxx...

# Plain text response (default): just the access token
ya29.a0AfH6SM...

# .env format: GET /api/v1/token/{grant_id}.env
TAPAUTH_TOKEN=ya29.a0AfH6SM...
TAPAUTH_EXPIRES=1741194000
TAPAUTH_GRANT_ID=abc123
TAPAUTH_GRANT_SECRET=gs_xxx...

# .json format: GET /api/v1/token/{grant_id}.json
{
  "token": "ya29.a0AfH6SM...",
  "expires": "2026-03-05T17:00:00Z",
  "provider": "google",
  "grant_id": "abc123"
}

While pending — returns 202 (empty body)

4. Use the token

Call the provider API directly with the access_token. TapAuth is not a proxy.

Full example (curl)

# 1. Create a grant
curl -X POST https://tapauth.ai/api/v1/grants \
  -H "Content-Type: application/json" \
  -d '{"provider":"google","scopes":["calendar.readonly"]}'

# Response: {"grant_id":"...","grant_secret":"gs_...","approve_url":"...","status":"pending_registration"}

# 2. Send approve_url to user and wait for them to approve

# 3. Retrieve the token
curl -s https://tapauth.ai/api/v1/token/{grant_id} \
  -H "Authorization: Bearer gs_..."

# Response: ya29... (plain text access token)

# 4. Use the token
curl -H "Authorization: Bearer ya29..." \
  https://www.googleapis.com/calendar/v3/calendars/primary/events