Appearance
Authentication
Universal API uses Bearer token authentication for all API requests. This page covers every authentication method, how credentials are injected into your code, and security best practices.
Authentication Methods
All requests use the Authorization header:
Authorization: Bearer <token>The platform supports several token types, checked in this priority order:
| Token Type | Format | Use Case |
|---|---|---|
| User Token | uapi_ut_xxxx_... | Primary API access (recommended) |
| Role Token | uapi_rt_xxxx_... | Scoped access with specific API keys |
| Cognito JWT | eyJ... | Browser sessions (automatic) |
| Anonymous | (no header) | Public resources only, IP rate-limited |
User Tokens (Recommended)
User tokens are the primary way to authenticate with Universal API. Each user can have up to 2 tokens.
Create a token:
bash
curl -s -X POST https://api.universalapi.co/user/token/create \
-H "Authorization: Bearer YOUR_EXISTING_TOKEN" \
-H "Content-Type: application/json" \
-d '{"tokenName": "My Laptop"}' | jqResponse:
json
{
"message": "Token created successfully",
"token": "uapi_ut_d468_a1b2c3d4e5f6...",
"tokenId": "tok-xxx",
"tokenName": "My Laptop",
"prefix": "uapi_ut_d468"
}WARNING
The full token is only returned once at creation time. The platform stores a SHA-256 hash — the raw token cannot be retrieved later. Save it immediately.
List your tokens:
bash
curl -s https://api.universalapi.co/user/token/list \
-H "Authorization: Bearer YOUR_TOKEN" | jqRevoke a token:
bash
curl -s -X POST https://api.universalapi.co/user/token/revoke \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"tokenId": "tok-xxx"}' | jqRole Tokens (Advanced)
Role tokens carry their own set of third-party API keys. They're designed for authors who want to provide their own keys (e.g., SerpAPI, OpenAI) so users don't need to bring their own.
How they work:
- Author creates a role token with specific keys attached
- Author sets
authorRoleTokenon their MCP server or agent - When a user invokes the resource, the author's keys from the role token are injected automatically
- Author keys take priority over user keys (author overrides user)
Create a role token:
bash
curl -s -X POST https://api.universalapi.co/user/token/create \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tokenName": "SerpAPI Role",
"tokenType": "role",
"keys": {
"serpapi": "your-serpapi-key-here"
}
}' | jqBrowser Sessions (Cognito JWT)
When you use the web UI at universalapi.co, authentication is handled automatically via AWS Cognito. The browser sends a JWT token in the Authorization header — no manual token management needed.
Third-Party API Keys
Many resources need external API keys to function (e.g., SerpAPI for web search, AWS credentials for Bedrock). Universal API provides a secure key storage system.
Storing Keys
Store your API keys at universalapi.co/keys or via the API:
bash
curl -s -X POST https://api.universalapi.co/keys/store \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"serviceName": "serpapi",
"apiKey": "your-serpapi-key-here"
}' | jqHow Keys Are Injected
When you invoke a resource, your stored keys are automatically injected into the runtime:
| Resource Type | How to Access Keys |
|---|---|
| MCP Servers | process.env.SERPAPI_KEY (flattened to env vars) |
| Agents | os.environ['UAPI_KEYS_JSON'] (JSON dict) |
Key naming convention for MCP servers:
Keys are flattened to uppercase env vars with _KEY suffix:
serpapi→process.env.SERPAPI_KEYopenai→process.env.OPENAI_KEYaws→process.env.AWS_KEY
Key Priority (Author vs User)
When both an author and a user have keys for the same service, author keys take priority — but only in MCP servers:
MCP Servers: Author keys (from authorRoleToken) > User keys
Agents: User keys only (author keys are never injected)Why are author keys excluded from agents?
Author keys are only injected into MCP server code, which the author controls. When an agent needs author-provided API access, the author creates an MCP server with their authorRoleToken and the agent connects to it via MCPClient. The agent invokes tools over HTTP and receives results — but never sees the underlying credentials. This is a capability-based security model.
For Resource Authors
To provide your own API keys for users:
- Create a Role Token with your keys attached
- Set
authorRoleTokenon your MCP server - Create an agent that connects to that MCP server
- Users get the capability without seeing your credentials
Common Services
| Service Name | Used By | Example |
|---|---|---|
serpapi | SerpAPI web search | Google search, Reddit search |
openai | OpenAI API | GPT models |
aws | AWS services | Bedrock, S3, Textract |
github | GitHub API | Repository access |
google | Google OAuth | Gmail, Calendar, Drive |
OAuth Connections
For services that use OAuth (Google Suite), connect your account at universalapi.co/keys:
- Click "Connect Google"
- Authorize access to Gmail, Calendar, and Drive
- Tokens are stored securely and refreshed automatically every 15 minutes
Once connected, MCP servers like google-suite can access your Gmail, Calendar, and Drive on your behalf.
Using Authentication in Your Code
In curl
bash
curl -s https://api.universalapi.co/user/info \
-H "Authorization: Bearer uapi_ut_xxxx_your_token_here"In Python
python
import requests
TOKEN = "uapi_ut_xxxx_your_token_here"
headers = {"Authorization": f"Bearer {TOKEN}"}
response = requests.get("https://api.universalapi.co/user/info", headers=headers)
print(response.json())In JavaScript/Node.js
javascript
const TOKEN = "uapi_ut_xxxx_your_token_here";
const response = await fetch("https://api.universalapi.co/user/info", {
headers: { "Authorization": `Bearer ${TOKEN}` }
});
const data = await response.json();In Claude Desktop / Cline
json
{
"mcpServers": {
"my-server": {
"url": "https://mcp.api.universalapi.co/mcp/SERVER_ID",
"headers": {
"Authorization": "Bearer uapi_ut_xxxx_your_token_here"
}
}
}
}Key Security Architecture
The platform enforces strict isolation between three key types:
| Key Type | Injected Into | Purpose |
|---|---|---|
| User keys | Agents + MCP servers | Your own API keys (OpenAI, AWS, etc.) |
| Author keys | MCP servers only | Author-provided keys for their resources |
| Platform keys | Neither (invisible) | Internal Bedrock access, infrastructure |
How It Works
┌──────────────────────┐ ┌──────────────────────┐
│ Agent Runtime │ │ MCP Server Runtime │
│ │ tool │ (author-controlled) │
│ Sees: │ call │ │
│ ✅ User keys │ ──────► │ Sees: │
│ ✅ Bearer token │ │ ✅ Author keys │
│ ❌ Author keys │ result │ ✅ User keys │
│ ❌ Platform keys │ ◄────── │ ❌ Platform keys │
└──────────────────────┘ └──────────────────────┘The agent gets the capability to invoke tools, not the credentials backing them. The MCP protocol has no mechanism for a client to request the server's environment variables — only tool results cross the boundary.
Security
How Tokens Are Stored
- Raw tokens are never stored — only SHA-256 hashes
- Tokens are validated by hashing the incoming token and comparing against stored hashes
- Third-party API keys are encrypted at rest in DynamoDB
What Tokens Can Access
- User tokens (
uapi_ut_*): Full access to your account — all resources, all stored keys - Role tokens (
uapi_rt_*): Only the keys explicitly attached to the role token - Anonymous: Public resources only, rate-limited by IP
Best Practices
- Never commit tokens to git — use environment variables
- Use role tokens for shared resources — don't expose your user token
- Rotate tokens regularly — revoke old tokens and create new ones
- Set credit limits on tokens to prevent runaway costs
- Use the minimum scope needed — role tokens for specific use cases, user tokens for personal use