SDKs
Mushu provides auto-generated SDKs with full type definitions. These are generated directly from our OpenAPI specifications, so they're always in sync with the API.
Python
Install the Python SDK:
pip install mushu Available Services
Each service has a typed client accessible via mushu.client():
| Service | Client | Base URL |
|---|---|---|
| Auth | mushu.client("auth") | auth.mushucorp.com |
| Notify | mushu.client("notify") | notify.mushucorp.com |
| Media | mushu.client("media") | media.mushucorp.com |
| Pay | mushu.client("pay") | pay.mushucorp.com |
| Geo Search | mushu.client("geo_search") | geosearch.mushucorp.com |
| Leaderboards | mushu.client("leaderboards") | leaderboards.mushucorp.com |
| Streaks | mushu.client("streaks") | streaks.mushucorp.com |
Example: Geo Search
import mushu
from mushu.geo_search.api.items import put_item
from mushu.geo_search.api.search import search_items
from mushu.geo_search.models import PutItemRequest, SearchRequest
# Initialize client with API key
client = mushu.client("geo_search", api_key="msk_your_api_key")
# Index a location
await put_item.asyncio_detailed(
collection="places",
id="cafe-123",
client=client,
body=PutItemRequest(
name="Blue Bottle Coffee",
description="Third wave coffee shop",
lat=37.7749,
lng=-122.4194,
tags=["coffee", "wifi"],
),
)
# Search by location + text + tags
response = await search_items.asyncio_detailed(
collection="places",
client=client,
body=SearchRequest(
lat=37.78,
lng=-122.41,
radius_km=5.0,
text="coffee",
tags=["wifi"], # AND: all tags must match
),
)
for item in response.parsed.items:
print(f"{item.name} - {item.distance_km:.1f}km away") Example: Notifications
import mushu
from mushu.notify.api.push import send_notification
from mushu.notify.models import SendNotificationRequest, Alert
client = mushu.client("notify", api_key="msk_your_api_key")
# Send a push notification
await send_notification.asyncio_detailed(
tenant_id="tenant_123",
client=client,
body=SendNotificationRequest(
user_id="user_456",
alert=Alert(title="Hello", body="From your server"),
),
) Sync vs Async
Each API function has both sync and async variants:
# Async (recommended for web apps)
response = await search_items.asyncio_detailed(...)
# Sync (for scripts, CLI tools)
response = search_items.sync_detailed(...) TypeScript
Install the TypeScript types:
npm install @mushu/sdk Usage:
import type { components as MediaTypes } from '@mushu/sdk/media';
import type { components as AuthTypes } from '@mushu/sdk/auth';
type MediaItem = MediaTypes['schemas']['MediaItem'];
type UserResponse = AuthTypes['schemas']['UserResponse'];
async function uploadMedia(orgId: string, file: File): Promise {
const request: MediaTypes['schemas']['UploadUrlRequest'] = {
org_id: orgId,
filename: file.name,
content_type: file.type,
size_bytes: file.size,
};
const response = await fetch('/media/upload-url', {
method: 'POST',
body: JSON.stringify(request),
});
return response.json();
} OpenAPI Specs
The raw OpenAPI specifications are available at each service endpoint. Use these to generate SDKs for other languages or to explore the API in tools like Swagger UI.
| Service | OpenAPI Spec |
|---|---|
| Auth | auth.mushucorp.com/openapi.json |
| Notify | notify.mushucorp.com/openapi.json |
| Media | media.mushucorp.com/openapi.json |
| Pay | pay.mushucorp.com/openapi.json |
| Geo Search | geosearch.mushucorp.com/openapi.json |
| Leaderboards | leaderboards.mushucorp.com/openapi.json |
| Streaks | streaks.mushucorp.com/openapi.json |
Generating Custom SDKs
Use OpenAPI Generator to create SDKs for other languages:
# Generate a Go client
openapi-generator-cli generate \
-i https://media.mushucorp.com/openapi.json \
-g go \
-o ./mushu-go
# Generate a Ruby client
openapi-generator-cli generate \
-i https://media.mushucorp.com/openapi.json \
-g ruby \
-o ./mushu-ruby Error Handling
All error responses follow a standard format:
{
"detail": "Human-readable error message",
"code": "ERROR_CODE"
} Error Codes
| Code | HTTP Status | Description | Retryable |
|---|---|---|---|
UNAUTHORIZED | 401 | Invalid or missing token | No (refresh token) |
FORBIDDEN | 403 | Not authorized for this resource | No |
NOT_FOUND | 404 | Resource does not exist | No |
INVALID_REQUEST | 400 | Validation error | No (fix request) |
RATE_LIMITED | 429 | Too many requests | Yes (wait) |
INTERNAL_ERROR | 500 | Server error | Yes |
Media-Specific Errors
| Code | Description |
|---|---|
FILE_TOO_LARGE | File exceeds size limit (100MB images, 500MB videos) |
UNSUPPORTED_MEDIA_TYPE | Content type not supported |
UPLOAD_NOT_FOUND | Upload URL expired or file not uploaded |
MEDIA_NOT_READY | Media still processing |
VIDEO_CODEC_UNSUPPORTED | Video codec not supported for transcoding |
TRANSCODE_FAILED | Video transcoding failed |