一键导入
authentication
Obtain and refresh JWT access tokens, and manage API keys for the Spuree V1 API
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Obtain and refresh JWT access tokens, and manage API keys for the Spuree V1 API
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Guides people through using Spuree for the first time. Always use this skill when the user asks how to use Spuree skills or tools, what Spuree can do, which Spuree capabilities are available, for Spuree help or a tutorial, or to get started with Spuree. Explains the public capability set, confirms the connection with a safe read-only first step, and offers a guided walkthrough without searching the user's workspace files for documentation.
List recent folders across projects; create, update, delete, and browse folders (sessions), including assets, files, and batch downloads
Search, get, create, upload (single & multipart), update, and delete files in Spuree projects with checksum-verified upload flow
Create, list, update, delete, and share projects in Spuree, including browsing project contents
Manage project sharing invitations in Spuree — list, accept, decline, cancel, and resend invitations for non-workspace members
| name | authentication |
| description | Obtain and refresh JWT access tokens, and manage API keys for the Spuree V1 API |
Spuree is an agent-friendly cloud storage. Projects contain folders (nestable) and files at any level. Authenticate with a JWT token or API key to access all V1 endpoints.
Tokens follow OAuth2 conventions and are issued as NextAuth-compatible JWTs.
Use this skill when an agent needs to:
First-time setup — three options:
export SPUREE_API_KEY="<your-api-key>"
If the user provides their email and password, the agent can set up its own API key:
POST /auth/token to get a temporary JWTPOST /v1/api-keys$SPUREE_API_KEYThe agent can authenticate without the user sharing their password:
source=api and the port:
https://studio.spuree.com/auth/signin?source=api&port=<port>
The user logs in via Google SSO (or email/password) in the browser.http://localhost:<port>/callback?token=<exchange-code>. The agent receives the exchange code from this callback (valid for 60 seconds).curl -X POST "https://studio.spuree.com/api/auth/token/exchange" \
-H "Content-Type: application/json" \
-d '{"code": "<exchange-code>"}'
POST /v1/api-keys) and store it in $SPUREE_API_KEY.Once $SPUREE_API_KEY is set, the agent authenticates with X-API-Key: $SPUREE_API_KEY on all requests. No login or token refresh needed.
Verify it works — ask your agent:
"List my Spuree projects"
The agent should show you which projects you have access to. If it works, your API key is set up correctly.
Try it out — ask your agent something like:
"Upload this file to my Spuree project"
Spuree uses two hosts:
| Host | Purpose | Endpoints |
|---|---|---|
https://studio.spuree.com/api | Authentication (login, refresh, exchange) | /auth/token, /auth/token/refresh, /auth/token/exchange |
https://data.spuree.com/api | All V1 data APIs (projects, files, etc.) | /v1/projects, /v1/files, /v1/api-keys, ... |
All other skills in this repo use https://data.spuree.com/api. Only the token endpoints below use studio.spuree.com.
| Token | Lifetime | Format |
|---|---|---|
access_token | 1 hour | NextAuth JWT |
refresh_token | 30 days | Opaque hex string |
exchange_code | 60 seconds | Opaque string |
The access_token is what you pass as Authorization: Bearer <access_token> to V1 API endpoints.
Alternatively, you can create API keys for long-lived, non-interactive access. API keys are passed via X-API-Key header and can be scoped to specific organizations.
All three endpoints return the same OAuth2-compliant response:
{
"access_token": "eyJhbGciOiJkaXIiLCJlbmMiOi...",
"refresh_token": "a1b2c3d4e5f6...",
"expires_in": 3600,
"user": {
"id": "64a7b8c9d1e2f3a4b5c6d7e8",
"email": "user@example.com",
"name": "User Name",
"image": "https://...",
"organizationId": "64a7b8c9d1e2f3a4b5c6d7f0",
"role": "admin",
"workspaces": [
{
"workspaceId": "64a7b8c9d1e2f3a4b5c6d7f1",
"workspaceName": "My Workspace",
"role": "owner"
}
]
}
}
Log in with email and password.
Description: Validates credentials and returns an access token and refresh token. Rate limited to 10 requests per minute per IP.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | User's email address |
password | string | Yes | User's password |
Status Codes:
| Code | Description |
|---|---|
| 200 | Login successful, tokens returned |
| 400 | Invalid request body or missing fields |
| 401 | Invalid email or password, or account locked |
| 429 | Rate limit exceeded (10 req/min) |
| 500 | Internal server error |
Error Messages (401):
| Message | Cause |
|---|---|
Invalid email or password | Wrong credentials |
Password is not set for this user | User registered via OAuth only |
Account is temporarily locked... | Too many failed attempts (5 failures → 15 min lock) |
Example:
curl -X POST "https://studio.spuree.com/api/auth/token" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "mypassword"
}'
Refresh an expired access token.
Description: Exchanges a valid refresh token for a new access token and refresh token pair. The old refresh token is atomically revoked to prevent reuse. Rate limited to 10 requests per minute per IP.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
refresh_token | string | Yes | The refresh token from a previous login or refresh |
Status Codes:
| Code | Description |
|---|---|
| 200 | New tokens issued |
| 400 | Missing refresh token |
| 401 | Invalid or expired refresh token |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
Example:
curl -X POST "https://studio.spuree.com/api/auth/token/refresh" \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "a1b2c3d4e5f6..."
}'
Notes:
refresh_token for subsequent refreshes.Exchange an authorization code for tokens.
Description: Exchanges a one-time authorization code for an access token and refresh token. Used by agents and desktop apps that authenticate via the browser (see Getting Started Option C). The login flow starts at studio.spuree.com/auth/signin?source=api — after the user completes login, the exchange code is delivered to the agent's local callback server. Rate limited to 10 requests per minute per IP.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
code | string | Yes | The authorization exchange code |
Status Codes:
| Code | Description |
|---|---|
| 200 | Tokens issued |
| 400 | Missing exchange code |
| 401 | Invalid or expired exchange code |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
Example:
curl -X POST "https://studio.spuree.com/api/auth/token/exchange" \
-H "Content-Type: application/json" \
-d '{
"code": "exchange-code-here"
}'
Notes:
API keys provide long-lived authentication for automated workflows. They are scoped to a user and optionally restricted to specific organizations.
All V1 endpoints accept either Authorization: Bearer <jwt> or X-API-Key: <api-key>. When both are provided, JWT takes priority.
Create a new API key.
Auth: Requires JWT (Bearer token only, not API key).
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Descriptive name for the key |
scopes | object | No | { "organizations": ["orgId1", ...] } — restrict to specific orgs. Omit for all orgs. |
expiresAt | datetime | No | Expiration timestamp (ISO 8601). Omit for no expiry. |
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "CI Pipeline Key",
"key": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"createdAt": "2024-01-15T10:00:00Z",
"expiresAt": null,
"lastUsedAt": null,
"scopes": { "organizations": ["64a7b8c9d1e2f3a4b5c6d7f0"] },
"status": "active"
}
Important: The
keyfield is only returned once at creation. Store it securely.
Example:
curl -X POST "https://data.spuree.com/api/v1/api-keys" \
-H "Authorization: Bearer $SPUREE_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "CI Pipeline Key",
"scopes": { "organizations": ["64a7b8c9d1e2f3a4b5c6d7f0"] }
}'
List all active API keys for the authenticated user.
Auth: Requires JWT (Bearer token only).
Response:
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "CI Pipeline Key",
"createdAt": "2024-01-15T10:00:00Z",
"expiresAt": null,
"lastUsedAt": "2024-03-10T14:30:00Z",
"scopes": { "organizations": ["64a7b8c9d1e2f3a4b5c6d7f0"] },
"status": "active"
}
]
Example:
curl "https://data.spuree.com/api/v1/api-keys" \
-H "Authorization: Bearer $SPUREE_ACCESS_TOKEN"
Revoke an API key (soft delete).
Auth: Requires JWT (Bearer token only).
Response:
{ "success": true }
Example:
curl -X DELETE "https://data.spuree.com/api/v1/api-keys/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer $SPUREE_ACCESS_TOKEN"
Store tokens in environment variables using these standard names:
SPUREE_ACCESS_TOKEN=eyJhbGci... # JWT access token (1 hour)
SPUREE_REFRESH_TOKEN=a1b2c3d4... # For refreshing access token (30 days)
SPUREE_API_KEY=a1b2c3d4... # API key (64-char hex, long-lived)
All Spuree skills reference these variable names. V1 endpoints accept either Authorization: Bearer $SPUREE_ACCESS_TOKEN or X-API-Key: $SPUREE_API_KEY.
Obtain tokens with email and password:
POST /auth/token → { access_token, refresh_token, expires_in, user }
Use access token for V1 API calls:
Authorization: Bearer {access_token}
Refresh before the token expires (every ~55 minutes):
POST /auth/token/refresh → { access_token, refresh_token, ... }
expires_in is 3600 (1 hour). Refresh proactively at ~55 minutes to avoid failed requests.refresh_token — old ones are revoked after use.For CI/CD pipelines or long-running agents that can't refresh tokens:
POST /v1/api-keys → { key: "a1b2c3d4..." }
X-API-Key: a1b2c3d4...
API keys don't expire by default (unless expiresAt is set) and don't need refreshing.
| Error | Cause | Resolution |
|---|---|---|
| 401 (invalid credentials) | Wrong email or password | Verify credentials |
| 401 (account locked) | 5 failed login attempts | Wait 15 minutes, then retry |
| 401 (invalid refresh token) | Token expired, revoked, or reused | Log in again with email/password |
| 401 (invalid exchange code) | Code expired or already used | Request a new exchange code |
| 429 (rate limit) | More than 10 requests/min from same IP | Wait and retry with backoff |
All authentication endpoints share the same rate limit: 10 requests per minute per IP. Implement exponential backoff when receiving 429 responses.