API Keys
Mushu supports two authentication methods: CLI tokens for interactive development, and API keys for server-to-server calls. This guide explains when to use each and how to create and manage API keys.
Authentication Methods
| Method | Use Case | Expiry | How to Get |
|---|---|---|---|
| CLI Token | Interactive development, CLI commands | 12 hours | mushu auth login |
| API Key | Backend servers, automated systems | Never (until deleted) | Dashboard or CLI |
When to Use API Keys
Use API keys when:
- Your backend server calls Mushu APIs
- You need a credential that doesn't expire
- You want to avoid token refresh logic
- You're integrating with CI/CD pipelines
Use CLI tokens when:
- Running commands from your terminal
- Testing APIs during development
- Any interactive, short-lived session
Creating API Keys
Via CLI
mushu api-key create --name "backend-server" --org ORG_ID Output:
{
"key_id": "key_abc123",
"key": "msk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"name": "backend-server",
"scopes": ["read", "write"],
"created_at": "2026-01-15T10:30:00Z"
} Important: The full key (msk_live_...) is only shown once.
Copy it immediately and store it securely. You cannot retrieve it later.
Via API
POST /orgs/{org_id}/api-keys
Authorization: Bearer YOUR_CLI_TOKEN
Content-Type: application/json
{
"name": "backend-server",
"scopes": ["read", "write"]
} API Key Scopes
Scopes control what operations an API key can perform:
| Scope | Permissions |
|---|---|
read | Read organizations, tenants, devices, media metadata |
write | Register devices, upload media, send notifications |
admin | Create/delete tenants, manage API keys, modify settings |
By default, keys are created with read and write scopes.
Use admin sparingly—only for management tools that need full access.
Creating a Read-Only Key
mushu api-key create --name "analytics" --org ORG_ID --scopes read Creating an Admin Key
mushu api-key create --name "admin-tool" --org ORG_ID --scopes read,write,admin Using API Keys
Include the API key in the Authorization header with the ApiKey scheme:
GET /orgs/{org_id}/tenants
Authorization: ApiKey msk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx Or use the X-API-Key header:
GET /orgs/{org_id}/tenants
X-API-Key: msk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx Example: Python (SDK)
import os
import mushu
from mushu.notify.api.push import send_notification
from mushu.notify.models import SendNotificationRequest, Alert
client = mushu.client("notify", api_key=os.environ["MUSHU_API_KEY"])
async def send_push(tenant_id: str, user_id: str, title: str, body: str):
response = await send_notification.asyncio_detailed(
tenant_id=tenant_id,
client=client,
body=SendNotificationRequest(
user_id=user_id,
alert=Alert(title=title, body=body),
),
)
return response.parsed Install the SDK: pip install mushu
Example: Node.js
const API_KEY = process.env.MUSHU_API_KEY;
async function uploadMedia(orgId, file) {
// Get upload URL
const { media_id, upload_url } = await fetch(
`https://media.mushucorp.com/media/upload-url`,
{
method: 'POST',
headers: {
'Authorization': `ApiKey ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
org_id: orgId,
filename: file.name,
content_type: file.type,
size_bytes: file.size,
}),
}
).then(r => r.json());
// Upload to presigned URL
await fetch(upload_url, {
method: 'PUT',
headers: { 'Content-Type': file.type },
body: file,
});
// Confirm upload
return fetch(`https://media.mushucorp.com/media/${media_id}/confirm`, {
method: 'POST',
headers: { 'Authorization': `ApiKey ${API_KEY}` },
}).then(r => r.json());
} Listing API Keys
mushu api-key list --org ORG_ID Output:
KEY_ID NAME SCOPES CREATED
key_abc123 backend-server read,write 2026-01-15
key_def456 analytics read 2026-01-10
key_ghi789 admin-tool read,write,admin 2026-01-01 Deleting API Keys
If a key is compromised or no longer needed, delete it immediately:
mushu api-key delete key_abc123 --org ORG_ID All requests using that key will fail after deletion.
Key Rotation
Rotate API keys periodically to limit the impact of potential compromises:
- Create a new key with the same scopes
- Update your server to use the new key
- Deploy and verify the new key works
- Delete the old key
Tip: Use environment variables for API keys in your servers. This makes rotation a config change instead of a code change.
Security Best Practices
- Never commit keys to source control - Use environment variables or secrets managers
- Use the minimum required scopes - A notification service doesn't need
admin - One key per service - If one is compromised, only rotate that one
- Rotate regularly - Quarterly rotation is a good baseline
- Monitor usage - Watch for unusual patterns in your Mushu dashboard
Key Prefixes
Mushu API keys use prefixes to indicate their type:
| Prefix | Environment |
|---|---|
msk_live_ | Production |
msk_test_ | Test/sandbox |
Test keys only work against sandbox endpoints and won't affect production data.
FAQ
Can I see my key again after creating it?
No. The full key is only shown once at creation time. If you lose it, delete the key and create a new one.
What happens if my key is compromised?
Delete it immediately using the CLI or dashboard. Then create a new key and update your servers.
Can I use API keys in my iOS app?
Yes, but be aware that keys bundled in apps can be extracted. For device registration this is usually acceptable. For admin operations, use your backend server instead.
How many keys can I create?
There's no limit. Create as many as you need for different services and environments.
Next Steps
- Quick Start - Get set up with the CLI
- Notify API Keys - Tenant-specific keys for notifications
- Media Quick Start - Upload your first image