Authentication
Learn how to authenticate with the Craft API. All API requests require proper authentication.
API Keys#
Creating an API Key#
- Log in to your Craft account
- Go to Account Settings → API Keys
- Click Create New Key
- Give your key a descriptive name
- Set permissions (read-only or read-write)
- Copy the key immediately (it won't be shown again)
Key Permissions#
| Permission | Access | | ---------- | -------------------------------------------- | | Read-Only | View projects, files, deployments | | Read-Write | Full access including create, update, delete |
Key Security#
- Never commit API keys to version control
- Use environment variables
- Rotate keys periodically
- Delete unused keys
Using API Keys#
Authorization Header#
Include your key in the Authorization header:
curl -X GET "https://api.craft.fast/v1/projects" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"
JavaScript Example#
const response = await fetch("https://api.craft.fast/v1/projects", {
headers: {
Authorization: `Bearer ${process.env.CRAFT_API_KEY}`,
"Content-Type": "application/json",
},
});
Using the SDK#
import { CraftClient } from "@craft/sdk";
const craft = new CraftClient({
apiKey: process.env.CRAFT_API_KEY,
});
// The SDK handles authentication automatically
const projects = await craft.projects.list();
OAuth 2.0#
For applications that need to act on behalf of users.
Supported Grant Types#
- Authorization Code
- Refresh Token
OAuth Flow#
1. Redirect User to Authorize
https://craft.fast/oauth/authorize?
client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.com/callback
&response_type=code
&scope=read write
2. Handle Callback
// GET /callback?code=AUTH_CODE
const code = searchParams.get("code");
const response = await fetch("https://api.craft.fast/v1/oauth/token", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
grant_type: "authorization_code",
code: code,
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
redirect_uri: "https://yourapp.com/callback",
}),
});
const { access_token, refresh_token, expires_in } = await response.json();
3. Use Access Token
const response = await fetch("https://api.craft.fast/v1/projects", {
headers: {
Authorization: `Bearer ${access_token}`,
},
});
4. Refresh Token
const response = await fetch("https://api.craft.fast/v1/oauth/token", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
grant_type: "refresh_token",
refresh_token: refresh_token,
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
}),
});
OAuth Scopes#
| Scope | Access |
| -------- | --------------------------------- |
| read | Read-only access to all resources |
| write | Create and modify resources |
| delete | Delete resources |
| admin | Administrative actions |
Request specific scopes:
scope=read write
Session Tokens#
For browser-based applications using cookies.
Session Flow#
- User logs in via Craft UI
- Session cookie is set
- API calls include cookie automatically
// Browser fetch with credentials
const response = await fetch("https://api.craft.fast/v1/me", {
credentials: "include",
});
Authentication Errors#
401 Unauthorized#
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing authentication"
}
}
Causes:
- Missing Authorization header
- Invalid API key
- Expired token
403 Forbidden#
{
"success": false,
"error": {
"code": "FORBIDDEN",
"message": "Insufficient permissions"
}
}
Causes:
- API key doesn't have required permissions
- Resource belongs to another user
Best Practices#
Environment Variables#
Store keys securely:
# .env.local
CRAFT_API_KEY=your_api_key_here
const apiKey = process.env.CRAFT_API_KEY;
Key Rotation#
Rotate keys periodically:
- Create a new key
- Update your application
- Test the new key
- Delete the old key
Scoped Keys#
Create keys with minimal permissions:
- Use read-only keys for display purposes
- Use write keys only where necessary
- Never use admin keys in client-side code
Token Storage#
For OAuth tokens:
- Store securely (encrypted)
- Never expose to client
- Implement refresh logic
- Handle expiration gracefully
Testing Authentication#
Verify Your Key#
curl -X GET "https://api.craft.fast/v1/me" \
-H "Authorization: Bearer YOUR_API_KEY"
Expected Response#
{
"success": true,
"data": {
"id": "user_123",
"email": "user@example.com",
"name": "John Doe"
}
}
Next Steps#
- Projects API - Manage projects
- Rate Limits - Understand limits
- API Overview - General reference