Organization Management Org CRUD, members, billing, transfer (agent→human), discovery
An organization (org) is a collector of workspaces. It can represent a company, a business unit, a team, or simply a personal collection. Orgs are the billable entity — storage, credits, and member limits are tracked at the org level. Every workspace and share lives under an org.
Profile IDs are 19-digit numeric strings. Most endpoints also accept the org's domain name (e.g., acme) in place of the numeric ID.
Internal vs External Orgs
Agents must call both GET /current/orgs/list/ and GET /current/orgs/list/external/ to discover all orgs they can access.
- Internal orgs (
member: true) — orgs you created or were invited to join as a member. You have org-level access: see all workspaces (subject to permissions), manage settings if admin, appear in the member list. Listed viaGET /current/orgs/list/. - External orgs (
member: false) — orgs you access only through workspace membership. A human invited you to their workspace but not to the org itself. You can see the org's name and basic public info, but cannot manage org settings, see other workspaces, or add org members. Listed viaGET /current/orgs/list/external/.
External orgs are the most common pattern when a human invites an agent to help with a specific project — they add the agent to a workspace but not to the org itself.
If the human later invites the agent to the org itself, it moves from external to internal and gains org-level access.
Org Field Constraints
| Field | Type | Min | Max | Regex / Rules | Default |
|---|---|---|---|---|---|
| domain | string | 2 | 80 | ^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?$ Lowercase alphanumeric + hyphens. Must be unique. Must not be reserved. | Required |
| name | string | 3 | 100 | Free text display name | null |
| description | string | 10 | 1000 | Free text | null |
| industry | string | — | — | Must be one of the values from GET /current/orgs/industries/ | null |
| perm_member_manage | string | — | — | 'Member or above', 'Admin or above', 'Owner only' | 'Member or above' |
| perm_authorized_domains | string | — | — | Email domain for auto-join (e.g., acme.com) | null |
| billing_email | string (email) | — | — | Valid email with reachable domain | User's email |
| accent_color | string (JSON) | — | — | JSON-encoded color object | null |
| background_color | string (JSON) | — | — | JSON-encoded color object | null |
| background_mode | string | — | — | One of the supported background display modes | null |
Member Roles and Permissions
| Role | Level | Can manage members | Can manage settings | Can manage billing | Can close org | Can transfer ownership |
|---|---|---|---|---|---|---|
| Owner | Highest | Yes | Yes | Yes | Yes | Yes |
| Admin | High | Yes (if perm_member_manage allows) | Yes | Yes | No | No |
| Member | Standard | If perm_member_manage = 'Member or above' | No | No | No | No |
| View | Lowest | No | No | No | No | No |
The perm_member_manage org setting controls the minimum role required to add, remove, or update members.
Organization CRUD
Create Organization
/current/org/create/
Auth required. Creates a new organization. The authenticated user becomes the owner.
Rate limits: 3/20s, 8/60s, 20/hr, 60/day
Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
| domain | string | Yes | 2-80 chars, lowercase alphanumeric + hyphens, must be unique and not reserved. Used as the org identifier in URLs. |
| name | string | No | 3-100 chars. Display name for the org. |
| description | string | No | Organization description. |
| industry | string | No | Industry type from predefined list (see GET /current/orgs/industries/). |
| accent_color | string (JSON) | No | Brand accent color as JSON. |
| background_color | string (JSON) | No | Background color as JSON. |
| background_mode | string | No | Background display mode. |
| facebook_url | string (URL) | No | Facebook page URL. Must be valid URL. |
| twitter_url | string (URL) | No | Twitter profile URL. Must be valid URL. |
| instagram_url | string (URL) | No | Instagram profile URL. Must be valid URL. |
| youtube_url | string (URL) | No | YouTube channel URL. Must be valid URL. |
| homepage_url | string (URL) | No | Organization website URL. Must be valid URL. |
| perm_member_manage | string | No | Who can manage members. See Org Field Constraints above. |
| perm_authorized_domains | string | No | Authorized email domain for auto-join. |
| billing_email | string (email) | No | Billing contact email. Defaults to user's email. |
Agent accounts are always assigned the agent plan (free: 50 GB storage, 5,000 credits/month, no trial, no expiration). Agents cannot select or change to a human plan.
curl example
curl -X POST "https://api.fast.io/current/org/create/" \
-H "Authorization: Bearer {jwt_token}" \
-d "domain=acme-corp" \
-d "name=Acme Corporation" \
-d "industry=technology"
Response (200 OK)
{
"result": "yes",
"response": {
"org": {
"id": "1234567890123456789",
"domain": "acme-corp",
"name": "Acme Corporation",
"description": null,
"logo": null,
"accent_color": null,
"closed": false,
"suspended": false
},
"has_free_trial": true,
"requires_payment": false,
"is_agent": false
}
}
When user is ineligible for free trial:
{
"result": "yes",
"response": {
"org": { "...": "..." },
"has_free_trial": false,
"requires_payment": true,
"no_trial_reason": "existing_org"
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| org | object | Organization resource object |
| org.id | string | 19-digit numeric organization ID |
| org.domain | string | URL-safe subdomain |
| org.name | string/null | Display name |
| org.description | string/null | Description |
| org.logo | string/null | Logo asset URL |
| org.accent_color | string/null | Brand color |
| org.closed | boolean | Whether org is closed |
| org.suspended | boolean | Whether org is suspended |
| has_free_trial | boolean | Whether the org has a free trial period |
| requires_payment | boolean | Whether payment is required before activation |
| is_agent | boolean | Whether the creating user is an agent |
| no_trial_reason | string | Reason free trial was denied (only when requires_payment is true) |
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "An invalid org domain was supplied." | Invalid domain format |
APP_ERROR_INPUT_INVALID | 400 | "The supplied org domain name is restricted." | Domain is reserved |
APP_ERROR_INPUT_INVALID | 400 | "The supplied org domain name is already in use." | Domain already taken |
APP_ERROR_INPUT_INVALID | 400 | "An invalid configuration was supplied..." | Metadata validation failed |
APP_ERROR_INPUT_INVALID | 400 | "Invalid JSON provided for {key}." | Malformed JSON in color fields |
APP_ERROR_UPDATE_ERROR | 400 | "There was an internal error processing your create request." | Org creation failed |
APP_INTERNAL_ERROR | 500 | "There was an internal error processing your create request." | Storage instance creation failed |
APP_INTERNAL_ERROR | 500 | "We were unable to create your organization..." | Commit failed |
APP_FORBIDDEN | 403 | GEO/risk restriction message | Request blocked by geo/risk check |
Get Org Details
/current/org/{org_id}/details/
Auth required. Returns full org details. Fields vary by the requesting user's permission level.
{org_id} accepts a 19-digit numeric ID or the org's domain name.
Access levels
| Role | Access | Notes |
|---|---|---|
| Owner | Full access | Includes encryption key, platform, storage config |
| Admin | Extended access | Includes billing info, permissions, subscriber status |
| Member | Standard access | Basic org info, status flags |
| View | Limited access | Public fields only |
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/details/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"org": {
"id": "1234567890123456789",
"domain": "acme-corp",
"name": "Acme Corporation",
"description": "Leading provider of innovation",
"logo": "https://assets.fast.io/org/logo.png",
"accent_color": "#0066CC",
"closed": false,
"locked": false,
"suspended": false,
"created": "2024-01-15 10:30:00",
"updated": "2024-06-20 14:45:00"
}
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| org.id | string | 19-digit numeric organization ID |
| org.domain | string | URL-safe subdomain |
| org.name | string/null | Display name |
| org.description | string/null | Description |
| org.logo | string/null | Logo asset URL |
| org.accent_color | string/null | Brand color |
| org.closed | boolean | Whether org is closed |
| org.locked | boolean | Whether org is locked |
| org.suspended | boolean | Whether org is suspended |
| org.created | string | Creation timestamp |
| org.updated | string | Last update timestamp |
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_DENIED | 403 | "You have not been granted access to this Org." | Insufficient permission |
Get Public Org Details
/current/org/{org_id}/public/details/
No authentication required. Returns limited public info about an org (name, domain, assets). IP-rate-limited.
Rate limits: 30/60s, 1000/hr, 5000/day (IP-based)
{org_id} accepts a 19-digit numeric ID or the org's domain name.
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/public/details/"
Response (200 OK)
{
"result": "yes",
"response": {
"org": {
"id": "1234567890123456789",
"domain": "acme-corp",
"name": "Acme Corporation",
"description": "Leading provider of innovation",
"logo": "https://assets.fast.io/org/logo.png",
"accent_color": "#0066CC"
}
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| org.id | string | 19-digit numeric organization ID |
| org.domain | string | URL-safe subdomain |
| org.name | string/null | Display name |
| org.description | string/null | Description |
| org.logo | string/null | Logo asset URL |
| org.accent_color | string/null | Brand color |
Update Organization
/current/org/{org_id}/update/
Auth required. Admin or above. Updates org details. Only provided fields are modified.
Rate limits: 1/3s, 5/10s, 20/60s, 100/hr
Access levels
| Role | Access |
|---|---|
| Owner | Full access |
| Admin | Full access |
| Member | Denied |
Request parameters (all optional)
| Name | Type | Description |
|---|---|---|
| domain | string | New URL-safe subdomain (2-80 chars, lowercase alphanumeric + hyphens). |
| name | string | Display name (3-100 chars). Send "null" to clear. |
| description | string | Description. Send "null" or "" to clear. |
| industry | string | Industry type from predefined list. |
| accent_color | string (JSON) | Brand accent color as JSON. Send "null" to clear. |
| background_color | string (JSON) | Background color as JSON. Send "null" to clear. |
| background_mode | string | Background display mode. |
| use_background | string | Enable/disable background ("true"/"false"). |
| facebook_url | string (URL) | Facebook URL. |
| twitter_url | string (URL) | Twitter URL. |
| instagram_url | string (URL) | Instagram URL. |
| youtube_url | string (URL) | YouTube URL. |
| homepage_url | string (URL) | Organization website URL. |
| perm_member_manage | string | Member management permission level. |
| perm_authorized_domains | string | Authorized email domain for auto-join. |
| billing_email | string (email) | Billing contact email. Domain must be reachable. |
| owner_defined | string (JSON) | Custom owner-defined properties. Send "null" or "" to clear. |
curl example
curl -X POST "https://api.fast.io/current/org/1234567890123456789/update/" \
-H "Authorization: Bearer {jwt_token}" \
-d "name=Acme Corp Updated" \
-d "description=Updated description" \
-d "industry=technology"
Response (200 OK)
{
"result": "yes"
}
If no actual changes are detected, returns success immediately.
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "An invalid org domain was supplied." | Invalid domain format |
APP_ERROR_INPUT_INVALID | 400 | "The supplied org domain name is restricted." | Domain is reserved |
APP_ERROR_INPUT_INVALID | 400 | "The supplied org domain name is already in use." | Domain taken by another org |
APP_ERROR_INPUT_INVALID | 400 | "An invalid configuration was supplied..." | Metadata validation failed |
APP_ERROR_INPUT_INVALID | 400 | "Invalid JSON provided for {key}." | Malformed JSON |
APP_ERROR_INPUT_INVALID | 400 | "The email domain is invalid or cannot receive email." | Bad billing email domain |
APP_ERROR_UPDATE_ERROR | 400 | "There was an internal error processing your update request." | Commit failed |
Close Organization
/current/org/{org_id}/close/
Auth required. Owner only. Soft-deletes the organization. Active subscriptions are automatically cancelled.
Rate limits: 1/3s, 2/60s, 3/hr, 4/day
Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
| confirm | string | Yes | Must match the org domain name or org numeric ID as confirmation. |
curl example
curl -X POST "https://api.fast.io/current/org/1234567890123456789/close/" \
-H "Authorization: Bearer {jwt_token}" \
-d "confirm=acme-corp"
Response (202 Accepted)
{
"result": "yes"
}
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "The confirm field provided does not match." | Confirmation does not match domain or ID |
APP_ERROR_UPDATE_ERROR | 400 | "There was an internal error processing your request." | Failed to close org |
Storage deletion is deferred to the deletion system after a retention period.
Organization Assets
List Available Asset Types
/current/org/assets/
Auth required. Returns available org asset metadata types (e.g., logo, background images).
curl example
curl -X GET "https://api.fast.io/current/org/assets/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"assets": [
{
"name": "logo",
"mime_types": ["image/png", "image/jpeg"],
"max_size": 5242880
}
]
}
}
List Org Assets
/current/org/{org_id}/assets/
Auth required. Any member with at least View permission. Returns assets currently set on the org.
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/assets/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"assets": {
"logo": {
"url": "https://assets.fast.io/org/logo.png",
"mime_type": "image/png",
"size": 45678
}
}
}
}
Upload Org Asset
/current/org/{org_id}/assets/{asset_name}/
Auth required. Admin or above. Upload as multipart/form-data.
Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
| file | file (multipart) | Yes | The asset file to upload. |
| metadata | string (JSON array) | No | Additional metadata for the asset. |
curl example
curl -X POST "https://api.fast.io/current/org/1234567890123456789/assets/logo/" \
-H "Authorization: Bearer {jwt_token}" \
-F "file=@logo.png"
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_POST_FILE_MISSING | 400 | "Asset upload missing" | No file in the request |
APP_ERROR_INPUT_INVALID | 400 | "metadata invalid" | Metadata is not a valid array |
Delete Org Asset
/current/org/{org_id}/assets/{asset_name}/
Auth required. Admin or above.
curl example
curl -X DELETE "https://api.fast.io/current/org/1234567890123456789/assets/logo/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes"
}
Read Org Asset (Raw)
/current/org/{org_id}/assets/{asset_name}/read/
No authentication required. Returns the raw binary content of an org asset with appropriate Content-Type header. Useful for displaying logos and images directly.
HEAD requests return headers only.
Organization Members
Add or Invite a Member
/current/org/{org_id}/members/{email_or_user_id}/
Auth required. Permission governed by org's perm_member_manage setting.
Rate limits: 10/3s, 25/10s, 50/60s, 100/hr, 1000/day
The target is specified as a path parameter:
- Use a user ID (19-digit numeric) to add an existing user directly
- Use an email address to send an invitation
Request parameters (adding existing user by ID)
| Name | Type | Required | Description |
|---|---|---|---|
| permissions | string | Yes | Permission level: "member", "admin". Cannot add as "owner". |
| expires | string (datetime) | No | Membership expiration date. |
| notify | string | No | Notification preference. |
| force_notification | boolean | No | Force send a notification email. |
Request parameters (inviting by email)
| Name | Type | Required | Description |
|---|---|---|---|
| permissions | string | Yes | Permission level for the invitation: "member", "admin". |
| message | string | No | Custom invitation message. |
| expires | string (datetime) | No | Invitation expiration. |
curl example (add existing user)
curl -X POST "https://api.fast.io/current/org/1234567890123456789/members/9876543210987654321/" \
-H "Authorization: Bearer {jwt_token}" \
-d "permissions=member"
curl example (invite by email)
curl -X POST "https://api.fast.io/current/org/1234567890123456789/members/jane@example.com/" \
-H "Authorization: Bearer {jwt_token}" \
-d "permissions=member" \
-d "message=Welcome to the team!"
Response (200 OK) — direct add
{
"result": "yes"
}
Response (200 OK) — invitation created
{
"result": "yes",
"response": {
"invitation": {
"id": "eA1B2C3D4E5F6G7H8J9K0L1M2N3O4",
"invitee_email": "jane@example.com",
"entity_type": "org",
"state": "pending",
"created": "2024-01-15 10:30:00"
}
}
}
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "Invalid permission specified." | Invalid permission value |
APP_CANNOT_ADD_AS_OWNER | 403 | "Adding a member as an owner is not allowed" | Tried to add as owner (use transfer_ownership) |
APP_EXCEEDED_LIMIT | 429 | Limit message | Member limit exceeded |
Remove a Member
/current/org/{org_id}/members/{user_id}/
Auth required. Permission governed by org's perm_member_manage setting.
Rate limits: 1/3s, 2/10s, 5/60s, 20/hr, 100/day
The target user ID (19-digit numeric) is a path parameter.
curl example
curl -X DELETE "https://api.fast.io/current/org/1234567890123456789/members/9876543210987654321/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes"
}
List Org Members
/current/org/{org_id}/members/list/
Auth required. Any org member. Paginated.
Rate limits: 20/3s, 50/10s, 200/60s, 500/hr, 10000/day
Query parameters
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 100 | 1-500, number of items to return |
| offset | integer | 0 | Number of items to skip |
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/members/list/?limit=50&offset=0" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"users": [
{
"id": "1234567890123456789",
"account_type": "human",
"email_address": "owner@example.com",
"first_name": "John",
"last_name": "Doe",
"permissions": "owner"
},
{
"id": "1234567890123456780",
"account_type": "agent",
"email_address": "bot@example.com",
"first_name": "Service",
"last_name": "Bot",
"permissions": "admin"
}
],
"pagination": {
"total": 2,
"limit": 50,
"offset": 0,
"has_more": false
}
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| users | array | Array of member objects |
| users[].id | string | 19-digit numeric user ID |
| users[].account_type | string | "human" or "agent" |
| users[].email_address | string | User's email |
| users[].first_name | string | First name |
| users[].last_name | string | Last name |
| users[].permissions | string | Role: "owner", "admin", "member" |
| pagination.total | integer | Total number of members |
| pagination.limit | integer | Requested page size |
| pagination.offset | integer | Current offset |
| pagination.has_more | boolean | Whether more results exist |
Leave Organization (Self)
/current/org/{org_id}/member/
Auth required. Removes the authenticated user from the org. Owners cannot leave — they must transfer ownership or close the org first.
curl example
curl -X DELETE "https://api.fast.io/current/org/1234567890123456789/member/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes"
}
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "You cannot leave an org you are the owner of..." | User is the org owner |
APP_ERROR_INPUT_INVALID | 400 | "You cannot leave an org you are not a member of." | User is not a member |
Get Member Details
/current/org/{org_id}/member/{user_id}/details/
Auth required. Any org member.
Rate limits: 200/3s, 500/10s, 750/60s, 1000/hr, 2500/day
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/member/9876543210987654321/details/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"member": {
"id": "9876543210987654321",
"account_type": "human",
"email_address": "jane@example.com",
"first_name": "Jane",
"last_name": "Smith",
"permissions": "admin",
"invite": "accepted",
"notify": "Email me",
"expires": null
}
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| member.id | string | 19-digit numeric user ID |
| member.account_type | string | "human" or "agent" |
| member.email_address | string | User's email |
| member.first_name | string | First name |
| member.last_name | string | Last name |
| member.permissions | string | Role: "owner", "admin", "member" |
| member.invite | string | Invitation status |
| member.notify | string | Notification preference |
| member.expires | string/null | Membership expiration (ISO 8601) or null for no expiry |
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "The membership you specified does not exist." | User is not a member |
Update Member Permissions
/current/org/{org_id}/member/{user_id}/update/
Auth required. Permission governed by org's perm_member_manage setting.
Rate limits: 10/3s, 25/10s, 50/60s, 100/hr, 1000/day
Request parameters (all optional)
| Name | Type | Description |
|---|---|---|
| permissions | string | New permission level ("member", "admin") |
| expires | string (datetime) | Membership expiration date |
| notify | string | Notification preference |
curl example
curl -X POST "https://api.fast.io/current/org/1234567890123456789/member/9876543210987654321/update/" \
-H "Authorization: Bearer {jwt_token}" \
-d "permissions=admin"
Response (200 OK)
{
"result": "yes"
}
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "The membership you specified does not exist." | User is not a member |
Transfer Org Ownership
/current/org/{org_id}/member/{user_id}/transfer_ownership/
Auth required. Owner only. Transfers ownership of the org to the specified member. The current owner is demoted to admin.
Rate limits: 10/3s, 25/10s, 50/60s, 100/hr, 1000/day
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/member/9876543210987654321/transfer_ownership/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes"
}
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "You cannot transfer ownership to yourself." | Target is the current user |
APP_ERROR_INPUT_INVALID | 400 | "The membership you specified does not exist." | User is not an org member |
APP_ERROR_INPUT_INVALID | 400 | "Member is already an owner." | Target is already the owner |
APP_ERROR_UPDATE_ERROR | 400 | "Failed to update owner of the org." | Commit failed |
Join Organization
/current/org/{org_id}/members/join/
Auth required. Join an org via invite or domain-based auto-join.
Rate limits: 10/3s, 25/10s, 50/60s, 100/hr, 1000/day
Join methods
- Via invitation: Append the invitation key to the URL path:
.../join/{invitation_key}/optionally followed byacceptordecline. Default isaccept. - Via authorized domain: The org must have
perm_authorized_domainsset and the user's email domain must match. User is added as a Member.
curl example (invitation)
curl -X POST "https://api.fast.io/current/org/1234567890123456789/members/join/abc123def456/accept/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes"
}
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_DENIED | 403 | "This org does not allow you to join automatically..." | Domain auto-join not enabled |
APP_DENIED | 403 | "You are not allowed to join this org automatically..." | User's email domain does not match |
APP_EXCEEDED_LIMIT | 429 | Limit message | Member limit exceeded |
List Org Invitations
/current/org/{org_id}/members/invitations/list/
Auth required. Any org member. An optional state filter can be appended: .../list/pending/.
Rate limits: 10/3s, 25/10s, 50/60s, 100/hr, 1000/day
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/members/invitations/list/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"invitations": [
{
"id": "eA1B2C3D4E5F6G7H8J9K0L1M2N3O4",
"inviter": "John Doe",
"invitee_email": "jane@example.com",
"entity_type": "org",
"state": "pending",
"created": "2024-01-15 10:30:00",
"expires": "2024-02-15 10:30:00"
}
]
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| invitations | array | Array of invitation objects |
| invitations[].id | string | Invitation identifier |
| invitations[].inviter | string | Name of the user who sent the invitation |
| invitations[].invitee_email | string | Email address of the invitee |
| invitations[].entity_type | string | Always "org" for org invitations |
| invitations[].state | string | Invitation state: "pending", "accepted", "declined" |
| invitations[].created | string | Creation timestamp |
| invitations[].expires | string/null | Expiration timestamp |
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "An invalid invitation state was supplied." | Invalid state filter |
Update an Invitation
/current/org/{org_id}/members/invitation/{invitation_id}/
Auth required. Permission governed by org's perm_member_manage setting.
Rate limits: 10/60s, 20/600s, 30/hr
{invitation_id} can be the invitation ID or the invitee email address.
Request parameters (all optional)
| Name | Type | Description |
|---|---|---|
| state | string | New invitation state |
| permissions | string | Updated permission level |
| expires | string (datetime) | Updated expiration date |
curl example
curl -X POST "https://api.fast.io/current/org/1234567890123456789/members/invitation/eA1B2C3D4E5F6G7H8J9K0L1M2N3O4/" \
-H "Authorization: Bearer {jwt_token}" \
-d "permissions=admin"
Response (200 OK)
{
"result": "yes"
}
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "An invalid invitation ID or email was supplied." | Invalid identifier |
APP_ERROR_INPUT_INVALID | 400 | "Invitation not found." | Invitation does not exist |
APP_ERROR_INPUT_INVALID | 400 | "Invitation is not for an Org" | Wrong entity type |
APP_ERROR_INPUT_INVALID | 400 | "An invalid state was supplied." | Invalid state value |
APP_UPDATE_FAILED | 400 | "Failed to update invitation." | Commit failed |
Delete an Invitation
/current/org/{org_id}/members/invitation/{invitation_id}/
Auth required. Permission governed by org's perm_member_manage setting.
Rate limits: 10/60s, 20/600s, 30/hr
{invitation_id} can be the invitation ID or the invitee email address.
curl example
curl -X DELETE "https://api.fast.io/current/org/1234567890123456789/members/invitation/eA1B2C3D4E5F6G7H8J9K0L1M2N3O4/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes"
}
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_DELETE_FAILED | 400 | "Failed to delete invitation." | Deletion failed |
Organization Transfer (Agent to Human)
Agents build orgs, then transfer ownership to humans. The human gets the org plus all workspaces; the agent stays as admin. Only agent accounts can create/list/delete tokens; only human accounts can claim.
The claim URL for humans: https://go.fast.io/claim?token={token}
Create Transfer Token
/current/org/{org_id}/transfer/token/create/
Auth required. Agent owner only. Org must be on the agent plan.
Rate limits: 5/min, 20/hour, 50/day
Creates a transfer token: 64-character string, valid 72 hours. Max 5 active tokens per org.
curl example
curl -X POST "https://api.fast.io/current/org/1234567890123456789/transfer/token/create/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"transfer_token": {
"id": "eA1B2C3D4E5F6G7H8J9K0L1M2N3O4",
"token": "a1b2c3d4e5f6g7h8j9k0l1m2n3o4p5q6r7s8t9u0v1w2x3y4z5a6b7c8d9e0f1g2",
"org_id": 1234567890123456789,
"state": "pending",
"expires": "2026-02-04T12:00:00+00:00",
"created": "2026-02-01T12:00:00+00:00"
}
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| transfer_token.id | string | Opaque identifier of the transfer token |
| transfer_token.token | string | 64-character token string to share with the human user |
| transfer_token.org_id | integer | Organization being transferred |
| transfer_token.state | string | Token state: "pending" |
| transfer_token.expires | string | ISO 8601 expiry timestamp (72 hours from creation) |
| transfer_token.created | string | ISO 8601 creation timestamp |
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_AUTH_INVALID | 401 | "Authentication required" | Missing or invalid token |
APP_FORBIDDEN | 403 | "Only agent accounts can create org transfer tokens." | Non-agent user attempted creation |
APP_FORBIDDEN | 403 | "Transfer tokens can only be created for organizations on the agent plan." | Org not on agent plan |
APP_NOT_ACCEPTED | 406 | "Maximum of 5 active transfer tokens per organization." | Token limit reached |
List Transfer Tokens
/current/org/{org_id}/transfer/token/list/
Auth required. Agent owner only. Returns all active (pending) transfer tokens for the org.
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/transfer/token/list/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"results": 1,
"transfer_tokens": [
{
"id": "eA1B2C3D4E5F6G7H8J9K0L1M2N3O4",
"token": "a1b2c3d4e5f6g7h8j9k0l1m2n3o4p5q6r7s8t9u0v1w2x3y4z5a6b7c8d9e0f1g2",
"org_id": 1234567890123456789,
"state": "pending",
"expires": "2026-02-04T12:00:00+00:00",
"created": "2026-02-01T12:00:00+00:00"
}
]
}
}
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_AUTH_INVALID | 401 | "Authentication required" | Missing or invalid token |
APP_FORBIDDEN | 403 | "Only agent accounts can list org transfer tokens." | Non-agent user |
Delete Transfer Token
/current/org/{org_id}/transfer/token/{token_id}/
Auth required. Agent owner only. Soft-deletes a pending transfer token.
curl example
curl -X DELETE "https://api.fast.io/current/org/1234567890123456789/transfer/token/eA1B2C3D4E5F6G7H8J9K0L1M2N3O4/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"transfer_token": {
"id": "eA1B2C3D4E5F6G7H8J9K0L1M2N3O4",
"token": "a1b2c3d4e5f6g7h8j9k0l1m2n3o4p5q6r7s8t9u0v1w2x3y4z5a6b7c8d9e0f1g2",
"org_id": 1234567890123456789,
"state": "deleted",
"expires": "2026-02-04T12:00:00+00:00",
"created": "2026-02-01T12:00:00+00:00"
}
}
}
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_AUTH_INVALID | 401 | "Authentication required" | Missing or invalid token |
APP_FORBIDDEN | 403 | "Only agent accounts can delete org transfer tokens." | Non-agent user |
APP_FORBIDDEN | 403 | "Transfer token does not belong to this organization." | Token/org mismatch |
APP_MISSING | 404 | "Transfer token not found." | Invalid token ID |
APP_NOT_ACCEPTED | 406 | "Token cannot be deleted." | Token already claimed/expired/deleted |
Public Token Details (Preview Before Claiming)
/current/org/transfer/claim/public/details/
No auth required. IP-rate-limited. Preview transfer token details before claiming.
Rate limits: 15/10s, 100/hr, 500/day (IP-based)
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| token | string | Yes | 64-character transfer token string |
curl example
curl -X GET "https://api.fast.io/current/org/transfer/claim/public/details/?token=a1b2c3d4e5f6g7h8j9k0l1m2n3o4p5q6r7s8t9u0v1w2x3y4z5a6b7c8d9e0f1g2"
Response (200 OK)
{
"result": "yes",
"response": {
"transfer_token": {
"id": "eA1B2C3D4E5F6G7H8J9K0L1M2N3O4",
"state": "pending",
"is_claimable": true,
"expires": "2026-02-04T12:00:00+00:00",
"created": "2026-02-01T12:00:00+00:00"
},
"org": {
"id": "1234567890123456789",
"domain": "my-agent-org",
"name": "My Agent Org",
"description": "An org built by an AI agent",
"logo": null,
"accent_color": null,
"closed": false,
"suspended": false
},
"created_by": {
"id": "9876543210987654321",
"account_type": "agent",
"email_address": "agent@example.com",
"first_name": "Agent",
"last_name": "Smith"
}
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| transfer_token.id | string | Token identifier |
| transfer_token.state | string | "pending", "claimed", "expired", or "deleted" |
| transfer_token.is_claimable | boolean | true if the token is pending and not expired |
| transfer_token.expires | string | ISO 8601 expiry timestamp |
| transfer_token.created | string | ISO 8601 creation timestamp |
| org | object/null | Organization info. null if the org has been deleted. |
| created_by | object/null | Agent creator profile. null if the creator no longer exists. |
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "A transfer token is required." | Missing token query parameter |
APP_ERROR_INPUT_INVALID | 400 | "Invalid transfer token format." | Token string is not exactly 64 characters |
APP_MISSING | 404 | "Transfer token not found or invalid." | No token matches |
Claim Organization
/current/org/transfer/claim/
Auth required. Human users only.
Rate limits: 5/min, 10/hour, 30/day
Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
| token | string | Yes | 64-character transfer token string |
curl example
curl -X POST "https://api.fast.io/current/org/transfer/claim/" \
-H "Authorization: Bearer {jwt_token}" \
-d "token=a1b2c3d4e5f6g7h8j9k0l1m2n3o4p5q6r7s8t9u0v1w2x3y4z5a6b7c8d9e0f1g2"
Response (200 OK)
{
"result": "yes",
"response": {
"org": {
"id": "1234567890123456789",
"domain": "my-agent-org",
"plan": "free"
},
"previous_owner": {
"id": "9876543210987654321",
"account_type": "agent"
},
"workspaces_transferred": 3
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| org.id | string | Organization profile ID |
| org.domain | string | Organization domain |
| org.plan | string | New billing plan (typically "free") |
| previous_owner.id | string | Previous agent owner's user ID |
| previous_owner.account_type | string | Always "agent" |
| workspaces_transferred | integer | Number of workspaces whose membership was transferred |
What happens during claim
- Organization ownership transfers to the human user
- Previous agent owner becomes an admin member of the org
- Billing plan changes from agent to free (credit-based, no trial period)
- All workspaces: human becomes owner, agent becomes admin
- Transfer token marked as
"claimed" - Free trial period starts from the transfer date
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_AUTH_INVALID | 401 | "Authentication required" | Missing or invalid token |
APP_FORBIDDEN | 403 | "Agent accounts cannot claim organizations." | Agent user attempted claim |
APP_MISSING | 404 | "Transfer token not found or invalid." | Invalid token string |
APP_NOT_ACCEPTED | 406 | "This transfer token has expired." | Token past expiry |
APP_NOT_ACCEPTED | 406 | "This transfer token has already been used." | Token not pending |
APP_NOT_ACCEPTED | 406 | "This organization is no longer eligible for transfer." | Org not on agent plan |
Organization Discovery
List Internal Orgs
/current/orgs/list/
Auth required. Lists orgs where the user is a direct member (member: true).
Non-admin/non-owner members only see orgs with active subscriptions; admins and owners always see their orgs.
curl example
curl -X GET "https://api.fast.io/current/orgs/list/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"orgs": [
{
"id": "1234567890123456789",
"domain": "acme-corp",
"name": "Acme Corporation",
"description": "Leading provider of innovation",
"logo": "https://assets.fast.io/org/logo.png",
"accent_color": "#0066CC",
"closed": false,
"suspended": false,
"subscriber": true,
"user_status": "joined",
"member": true
}
]
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| orgs | array | Array of organization objects |
| orgs[].id | string | 19-digit numeric organization ID |
| orgs[].domain | string | URL-safe subdomain |
| orgs[].name | string/null | Display name |
| orgs[].description | string/null | Description |
| orgs[].logo | string/null | Logo asset URL |
| orgs[].accent_color | string/null | Brand color |
| orgs[].closed | boolean | Whether org is closed |
| orgs[].suspended | boolean | Whether org is suspended |
| orgs[].subscriber | boolean | Whether org has an active subscription |
| orgs[].user_status | string | "joined" or "available" |
| orgs[].member | boolean | Always true for this endpoint |
Subscription filtering
| User Role | Behavior |
|---|---|
| Owner | Always sees the org |
| Admin | Always sees the org |
| Member | Only sees the org if it has an active subscription |
List External Orgs
/current/orgs/list/external/
Auth required. Lists orgs where the user has access only through workspace membership (member: false).
Rate limits: 250/hr, 3000/day
curl example
curl -X GET "https://api.fast.io/current/orgs/list/external/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"orgs": [
{
"id": "1234567890123456780",
"domain": "partner-corp",
"name": "Partner Corporation",
"description": "External partner organization",
"logo": null,
"accent_color": "#FF6600",
"closed": false,
"suspended": false,
"subscriber": true,
"user_status": "available",
"member": false
}
]
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| orgs | array | Array of external organization objects |
| orgs[].user_status | string | Always "available" for external orgs |
| orgs[].member | boolean | Always false for this endpoint |
List All Orgs
/current/orgs/all/
Auth required. Lists all accessible orgs (joined + invited).
curl example
curl -X GET "https://api.fast.io/current/orgs/all/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"orgs": [
{
"id": "1234567890123456789",
"domain": "acme-corp",
"name": "Acme Corporation",
"description": "Leading provider of innovation",
"logo": "https://assets.fast.io/org/logo.png",
"accent_color": "#0066CC",
"closed": false,
"suspended": false,
"user_status": "joined"
}
]
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| orgs[].user_status | string | "joined" (already a member) or "available" (pending invitation) |
List Available Orgs
/current/orgs/available/
Auth required. Lists orgs available to join (not yet joined). Excludes orgs the user is already a member of.
curl example
curl -X GET "https://api.fast.io/current/orgs/available/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"orgs": [
{
"id": "1234567890123456782",
"domain": "new-company",
"name": "New Company",
"description": "An org you can join",
"logo": null,
"accent_color": "#FF6600",
"closed": false,
"suspended": false
}
]
}
}
Check Domain Availability
/current/orgs/check/domain/{domain_name}
Auth required. Checks if an org domain name is available for use.
Rate limits: 15/3s, 50/10s, 80/60s, 250/hr, 1000/day
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| {domain_name} | string | Yes | The domain name to check for availability. |
curl example
curl -X GET "https://api.fast.io/current/orgs/check/domain/acme-corp" \
-H "Authorization: Bearer {jwt_token}"
Response (202 Accepted) — domain available
{
"result": "yes"
}
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "An invalid name was supplied." | Domain format is invalid |
APP_NOT_ACCEPTABLE | 406 | "The supplied name is restricted." | Domain is reserved |
APP_NOT_ACCEPTABLE | 406 | "The supplied name is already in use." | Domain is taken |
List Industries
/current/orgs/industries/
Auth required. Returns available industry types for org profiles.
curl example
curl -X GET "https://api.fast.io/current/orgs/industries/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"technology": {
"title": "Technology",
"description": "Software, hardware, and IT services"
},
"healthcare": {
"title": "Healthcare",
"description": "Medical, pharmaceutical, and health services"
},
"finance": {
"title": "Finance",
"description": "Banking, investment, and financial services"
},
"education": {
"title": "Education",
"description": "Schools, universities, and training providers"
}
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| {key} | string | Machine-readable industry identifier (use this value in create/update requests) |
| {key}.title | string | Human-readable display name |
| {key}.description | string | Brief description of the industry category |
Billing
Create or Update Subscription
/current/org/{org_id}/billing/
Auth required. Admin or above. Creates or updates the org's billing subscription.
Rate limits: 10/60s, 20/600s, 30/hr
Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
| billing_plan | string | No | Target plan ID (must be a valid paid plan, e.g., "pro_monthly", "business_monthly"). |
curl example
curl -X POST "https://api.fast.io/current/org/1234567890123456789/billing/" \
-H "Authorization: Bearer {jwt_token}" \
-d "billing_plan=pro_monthly"
Response (201 Created) — new subscription
{
"result": "yes",
"response": {
"subscription": { "...": "..." },
"customer": { "...": "..." },
"setup_intent": {
"id": "seti_xxx",
"client_secret": "seti_xxx_secret_xxx",
"status": "requires_payment_method"
},
"is_active": false,
"is_trial_eligible": true,
"public_key": "pk_xxx"
}
}
Response (202 Accepted) — subscription updated.
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "An invalid plan was supplied." | Plan ID not recognized |
APP_ERROR_INPUT_INVALID | 400 | "Cannot create subscription for a free plan." | Tried to subscribe to free plan |
APP_NOT_ACCEPTED | 406 | "An error occurred updating your subscription..." | Subscription update failed |
APP_NOT_ACCEPTED | 406 | "An error occurred creating the payment intent..." | Intent creation failed |
Cancel Subscription
/current/org/{org_id}/billing/
Auth required. Owner only. Cancels the org's subscription.
Rate limits: 10/60s, 20/600s, 30/hr
curl example
curl -X DELETE "https://api.fast.io/current/org/1234567890123456789/billing/" \
-H "Authorization: Bearer {jwt_token}"
Response (202 Accepted)
{
"result": "yes",
"response": {
"status": "cancelled",
"message": "Subscription has been successfully cancelled",
"closed": false
}
}
If already cancelled:
{
"result": "yes",
"response": {
"status": "already_cancelled",
"message": "Subscription is already cancelled"
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| status | string | "cancelled" or "already_cancelled" |
| message | string | Human-readable status message |
| closed | boolean | Whether the account was also closed (plan-dependent) |
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_MISSING | 404 | "No subscription was found to cancel." | Org is not a subscriber |
APP_ERROR_GENERAL | 500 | "Your subscription failed to be canceled..." | Cancellation failed |
Get Billing Details
/current/org/{org_id}/billing/details/
Auth required. Admin or above. Returns subscription/billing details.
Rate limits: 500/600s, 10000/day
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/billing/details/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"subscription": { "...": "..." },
"customer": { "...": "..." },
"setup_intent": { "...": "..." },
"payment_intent": { "...": "..." },
"is_active": true,
"is_trial_eligible": false,
"is_cancelled": false,
"current_plan": "pro_monthly",
"previous_plan": null,
"public_key": "pk_xxx"
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| subscription | object | Payment provider subscription details |
| customer | object | Payment provider customer details |
| setup_intent | object/null | Active setup intent if exists |
| payment_intent | object/null | Active payment intent if exists |
| is_active | boolean | Whether subscription is currently active |
| is_trial_eligible | boolean | Whether org is eligible for a trial |
| is_cancelled | boolean | Whether subscription is cancelled |
| current_plan | string/null | Current plan ID |
| previous_plan | string/null | Previous plan ID (if changed) |
| public_key | string | Payment provider publishable key |
Get Credit Usage
/current/org/{org_id}/billing/usage/limits/credits/
Auth required. Admin or above. Returns credit consumption and limits.
Rate limits: 500/60s, 20000/day
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/billing/usage/limits/credits/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": true,
"credit_limits_enabled": true,
"free_org_mode": true,
"org_id": "1234567890123456789",
"plan": "free",
"over_limit": false,
"usage": {
"credits_used": 1200,
"credit_limit": 10000,
"credits_remaining": 8800,
"usage_percentage": 12.0
},
"period": {
"start": "2025-01-15T10:00:00+00:00",
"end": "2025-02-14T10:00:00+00:00",
"days_total": 30,
"days_elapsed": 10,
"days_remaining": 20
},
"renewal": {
"interval_days": 30,
"next_renewal": "2025-02-14T10:00:00+00:00"
},
"trial": null
}
Response fields
| Field | Type | Description |
|---|---|---|
| credit_limits_enabled | boolean | Whether the plan enforces credit limits |
| free_org_mode | boolean | true for free orgs (reductive model) |
| over_limit | boolean | Whether the org has exceeded its credit limit |
| usage.credits_used | integer | Credits consumed in the current period |
| usage.credit_limit | integer | Total credits available per period |
| usage.credits_remaining | integer | Credits remaining in the current period |
| usage.usage_percentage | number | Percentage of credits used |
| period.start | string | ISO 8601 start of the current billing period |
| period.end | string | ISO 8601 end of the current billing period |
| period.days_total | integer | Total days in the period |
| period.days_elapsed | integer | Days elapsed since period start |
| period.days_remaining | integer | Days remaining until renewal |
| renewal.interval_days | integer | Days between credit renewals |
| renewal.next_renewal | string/null | ISO 8601 timestamp when credits renew next |
| run_rate | object/null | Usage rate projections (shown after 25% of period or credits used) |
| trial | object/null | Trial info if applicable |
Credit costs: storage (100/GB), bandwidth (212/GB), AI tokens (1/100 tokens), document ingestion (10/page), video ingestion (5/sec), image ingestion (5/image), file conversions (25/each).
List Billable Members
/current/org/{org_id}/billing/usage/members/list/
Auth required. Admin or above. Paginated.
Rate limits: 1/2s, 2/10s, 5/60s, 15/hr, 50/day
Query parameters
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 100 | 1-500 |
| offset | integer | 0 | Items to skip |
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/billing/usage/members/list/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"billable_members": [
{
"id": "1234567890123456789",
"account_type": "human",
"email_address": "user@example.com",
"parents": {
"9876543210987654321": {
"permission": "member",
"date_joined": "2024-01-15 10:30:00"
}
}
}
]
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| billable_members | array | Array of billable member objects |
| billable_members[].id | string | 19-digit user ID |
| billable_members[].account_type | string | "human" or "agent" |
| billable_members[].email_address | string | User's email |
| billable_members[].parents | object | Map of workspace IDs to membership details |
Get Usage Meters
/current/org/{org_id}/billing/usage/meters/list/
Auth required. Admin or above. Returns detailed usage breakdown by meter.
Rate limits: 30/3s, 80/10s, 200/60s, 600/hr, 12000/day
Query parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| meter | string | Yes | — | Meter type (e.g., "storage_bytes", "bandwidth_bytes", "ai_tokens") |
| start_time | string (datetime) | No | 30 days ago | Start of time range |
| end_time | string (datetime) | No | Now | End of time range |
| workspace_id | string | No | — | Filter by workspace (19-digit ID) |
| share_id | string | No | — | Filter by share (19-digit ID) |
Only one of workspace_id or share_id can be specified at a time.
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/billing/usage/meters/list/?meter=storage_bytes&start_time=2024-01-01+00:00:00&end_time=2024-01-31+23:59:59" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"usage": {
"meter": "storage_bytes",
"total": 1073741824,
"cost": 0.50,
"credits": 500,
"start_time": "2024-01-01 00:00:00 UTC",
"end_time": "2024-01-31 23:59:59 UTC",
"interval_hours": 24,
"workspace_id": null,
"share_id": null,
"data_points": [
{
"start_time": "2024-01-01 00:00:00 UTC",
"end_time": "2024-01-02 00:00:00 UTC",
"value": 536870912,
"cost": 0.25,
"credits": 250
}
]
}
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| usage.meter | string | The meter type queried |
| usage.total | number | Total usage value for the period |
| usage.cost | number | Total cost in USD |
| usage.credits | number/null | Total credits consumed (null for direct-billed meters) |
| usage.start_time | string | Start of the queried range |
| usage.end_time | string | End of the queried range |
| usage.interval_hours | integer | Hours per data point (auto-calculated, max 30 points) |
| usage.data_points | array | Time-series data with value, cost, and credits per interval |
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_ERROR_INPUT_INVALID | 400 | "Must be one of the valid meter types" | Invalid meter type |
APP_ERROR_INPUT_INVALID | 400 | "Only one of workspace_id or share_id can be specified." | Both filters provided |
APP_ERROR_INPUT_INVALID | 400 | "Start time must be before end time." | Invalid time range |
APP_ERROR_INPUT_INVALID | 400 | "Time range must be at least 1 day." | Range too short |
APP_INTERNAL_ERROR | 500 | "Failed to retrieve usage data." | Database query failed |
List Available Plans
/current/org/billing/plan/list/
Auth required. Returns available billing plans. Filtered by account type.
- Agent accounts only see the
agentplan - Human accounts see human plans: free, pro, business
Agents cannot subscribe to human plans.
curl example
curl -X GET "https://api.fast.io/current/org/billing/plan/list/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"results": 3,
"defaults": {
"pro": "pro_monthly",
"business": "business_monthly"
},
"plans": [
{
"id": "free",
"name": "Free",
"category": "free",
"amount": 0
},
{
"id": "pro_monthly",
"name": "Pro",
"category": "pro",
"amount": 2900
},
{
"id": "business_monthly",
"name": "Business",
"category": "business",
"amount": 4900
}
]
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| results | integer | Number of available plans |
| defaults | object | Default plan IDs per category (pro, business) |
| plans | array | Array of plan detail objects |
| plans[].id | string | Plan identifier (use in subscription requests) |
| plans[].name | string | Display name |
| plans[].category | string | Plan category: "free", "pro", "business", "agent" |
| plans[].amount | integer | Price in cents (e.g., 2900 = $29.00) |
Create Workspace (from Org)
/current/org/{org_id}/create/workspace/
Auth required. Member or above. Creates a workspace within the org. Subject to plan feature availability and workspace creation limits.
Rate limits: 1/3s, 2/10s, 5/60s, 20/hr, 100/day
Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
| folder_name | string | Yes | URL-safe folder name for the workspace. Must be unique within the org. |
| name | string | Yes | Display name. |
| description | string | No | Workspace description. |
| perm_join | string | Yes | Who can auto-join from the org. Values: 'Member or above' (default), 'Admin or above', 'Only Org Owners'. |
| perm_member_manage | string | Yes | Who can manage workspace members. Values: 'Member or above' (default), 'Admin or above'. |
| intelligence | string | Yes (non-agents) | Enable AI features ("true"/"false"). Defaults to "true" for agent accounts. |
| accent_color | string (JSON) | No | Accent color as JSON. |
| background_color1 | string (JSON) | No | Primary background color as JSON. |
| background_color2 | string (JSON) | No | Secondary background color as JSON. |
curl example
curl -X POST "https://api.fast.io/current/org/1234567890123456789/create/workspace/" \
-H "Authorization: Bearer {jwt_token}" \
-d "folder_name=project-alpha" \
-d "name=Project Alpha" \
-d "perm_join=Member or above" \
-d "perm_member_manage=Admin or above" \
-d "intelligence=true"
Response (200 OK)
{
"result": "yes",
"response": {
"workspace": {
"id": "1234567890123456780",
"folder_name": "project-alpha"
}
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| workspace.id | string | 19-digit numeric workspace ID |
| workspace.folder_name | string | URL-safe folder name |
Error responses
| Error Code | HTTP Status | Message | Cause |
|---|---|---|---|
APP_FEATURE_LIMIT | 403 | "Workspace creation is not available on your current plan." | Feature disabled |
APP_FEATURE_LIMIT | 403 | "You have reached your workspace creation limit." | Limit exceeded |
APP_NOT_ACCEPTABLE | 406 | "The supplied workspace folder name is already in use." | Duplicate folder name |
APP_ERROR_INPUT_INVALID | 400 | "An invalid workspace folder name was supplied." | Invalid folder name |
APP_ERROR_INPUT_INVALID | 400 | "An invalid configuration was supplied..." | Metadata validation failed |
List Workspaces in Org
/current/org/{org_id}/list/workspaces/
Auth required. Lists accessible workspaces within the org.
Rate limits: Org members: 500/hr, 5000/day. External users: 100/hr, 500/day.
Query parameters
| Name | Type | Default | Description |
|---|---|---|---|
| archived | string | "false" | "true" to show archived workspaces, "false" for active |
Access levels
| Role | Access | Notes |
|---|---|---|
| Owner | Full access | Sees all workspaces |
| Admin | Full access | Sees all workspaces |
| Member | Filtered | Sees workspaces matching join permission level |
| External | Filtered | Sees only workspaces where they are a direct member |
curl example
curl -X GET "https://api.fast.io/current/org/1234567890123456789/list/workspaces/" \
-H "Authorization: Bearer {jwt_token}"
Response (200 OK)
{
"result": "yes",
"response": {
"workspaces": [
{
"id": "1234567890123456780",
"folder_name": "project-alpha",
"name": "Project Alpha",
"description": "Main project workspace"
}
]
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| workspaces | array | Array of workspace objects |
| workspaces[].id | string | 19-digit numeric workspace ID |
| workspaces[].folder_name | string | URL-safe folder name |
| workspaces[].name | string | Display name |
| workspaces[].description | string/null | Workspace description |