Backend API Reference

REST API for workspace, project, model, chat, billing, and notification operations. Authenticate with an access token.

Backend API Reference

Base URL: https://app.nfyio.com/api

The backend API is a JSON REST surface. Authenticate every request with an access token:

curl https://app.nfyio.com/api/auth/me \
  -H "Authorization: Bearer $NFYIO_ACCESS_TOKEN"

S3 bucket and object operations (upload, download, list, multipart, presigned URLs) are not on this surface. Use the Object Storage endpoint instead.

Conventions

  • Identifiers are UUIDs called uid, returned as strings.
  • Timestamps are ISO 8601 in UTC: 2026-05-04T12:34:56.000Z.
  • Pagination is ?page=1&limit=50 where supported. Responses include pagination: { page, limit, total, totalPages }.
  • Filtering uses query parameters when documented per endpoint.

Standard envelope

Every response uses:

{
  "success": true,
  "data": { /* … */ }
}

or, on error:

{
  "success": false,
  "error": { "code": "STRING", "message": "human readable", "details": "optional" }
}

Common error codes

CodeHTTPMeaning
UNAUTHORIZED401Missing / invalid / expired token
ROUTE_FORBIDDEN403Access token’s route restriction blocks this path
MISSING_CONTEXT400Workspace / project context could not be resolved for the token
NOT_FOUND404Resource does not exist or is in another workspace
INVALID_INPUT400Body or query parameters failed validation
DUPLICATE_ENTRY409Unique constraint violation
QUOTA_EXCEEDED402Plan limit hit; check /billing/quota
INTERNAL_ERROR500Unhandled server error — retry, then contact support

Auth

GET /auth/me

Returns the user, workspace, project, and active team for the calling token.

curl https://app.nfyio.com/api/auth/me \
  -H "Authorization: Bearer $TOKEN"
{
  "success": true,
  "data": {
    "user": { "id": "kc-sub", "email": "...", "firstName": "Ada", "lastName": "Lovelace" },
    "workspaceId": "ws-uid",
    "projectId": "prj-uid",
    "selectedTeam": { "uid": "team-uid", "name": "Default" },
    "billingAccountUid": "ba-uid",
    "plan": { "name": "Pro", "type": "paid", "category": "standard" }
  }
}

PATCH /auth/profile

Update the calling user’s first/last name.

Body: { "firstName": "Ada", "lastName": "Lovelace" }. Returns the new values.

Workspaces

MethodPathPurpose
GET/workspacesList workspaces the user belongs to
POST/workspacesCreate a new workspace
GET/workspaces/:uidWorkspace detail
PUT/workspaces/:uidUpdate workspace
DELETE/workspaces/:uidDelete workspace (irreversible)

Projects

MethodPathPurpose
GET/projectsList projects in the active workspace
POST/projectsCreate a project
POST/projects/selectSwitch the session’s active project. Body: { "projectUid": "…" }
GET / PUT / DELETE/projects/:uidRead / update / delete

Teams

MethodPathPurpose
GET/teamsList teams in the workspace
POST/teamsCreate a team
POST/teams/switchSwitch the active team in the session
GET / PUT / DELETE/teams/:uidRead / update / delete

Members & invites

MethodPathPurpose
GET/team-members?teamUid=…List members of a team
POST/team-membersAdd a member directly
POST/team-members/inviteEmail an invite. Body: { email, teamUid, role: "modifier"|"viewer" }
GET / PUT / DELETE/team-members/:uidRead / change role / remove
GET/invitesList pending invites for the calling user
GET/invites/:idInvite detail
POST/invites/:id/acceptAccept an invite
POST/invites/:id/rejectReject an invite

Buckets (settings only)

These endpoints manage bucket records — naming, project assignment, RAG / embedding configuration, versioning, and lifecycle. They do not upload, download, list or delete objects. For that, use the S3 endpoint described in Object Storage.

MethodPathPurpose
GET/object-storage/buckets/check-name?name=…Returns { available: true|false }
GET/object-storage/buckets?page&limit&searchList buckets in active workspace
POST/object-storage/bucketsCreate a bucket. Body fields: name, region, projectUid, useReason ("hot"|"cold"), storageType ("standard"|"pro"|"cold"|"zip"), isEmbeddingsEnabled, embeddingModelUid, llmModelUid, embeddingApiKey, llmApiKey, isCDN. Returns { jobId } — poll with /object-storage/jobs/:jobId.
GET/object-storage/buckets/:bucketNameBucket detail (settings + indexing status)
PUT/object-storage/bucketsUpdate settings. Body must include current bucketName plus fields to change.
PUT/object-storage/buckets/:bucketName/versioningEnable / disable object versioning. Body: { enabled: true|false }
DELETE/object-storage/bucketsSoft-delete a bucket. Body: { bucketName }. Returns { jobId }.

Object metadata listing (no payload)

For convenience, the backend can return object metadata without going through the S3 endpoint. These are read-only and meant for dashboards / pickers — large transfers should still go through S3.

MethodPathPurpose
GET/object-storage/buckets/:bucketName/objects?prefix&page&limitList object keys + sizes + index status
GET/object-storage/buckets/:bucketName/objects/:key+Object metadata (size, type, indexed-at)
GET/object-storage/buckets/:bucketName/objects/:key+/contentStream object bytes (small reads only — prefer S3 GetObject)

RAG / Embeddings

MethodPathPurpose
GET/object-storage/buckets/:bucketName/embeddings/statusIndexing progress: { pending, processing, completed, failed } per file
GET/object-storage/buckets/:bucketName/embeddings/usageEmbedding token usage for the bucket
GET/object-storage/buckets/:bucketName/embeddings/search?q=…&limit=…&threshold=…Semantic search (returns chunk hits with scores)
POST/object-storage/buckets/:bucketName/embeddings/reindexReindex every object in the bucket
POST/object-storage/buckets/:bucketName/embeddings/reindex-incompleteReindex only pending / failed objects
POST/object-storage/test-embedding-keyValidate a user-provided embedding API key without saving it. Body: { modelUid, apiKey }
POST/object-storage/test-llm-keySame, for an LLM key

Models

The platform ships a catalog of LLM and embedding models. Owners can add custom entries.

MethodPathPurpose
GET/models?group=text|embeddingList models, optionally filtered by group
POST/modelsAdd a custom model
GET / PUT / DELETE/models/:uidRead / update / remove

Chat

MethodPathPurpose
POST/chatSend a message. Body: { bucketName, message, conversationId? }. Returns the model reply plus the updated conversation. RAG retrieval against the bucket runs automatically when the bucket has embeddings enabled.
GET/chat/conversationsList the user’s conversations
GET/chat/conversations/:conversationId/messagesFull message history of a conversation

Notifications

MethodPathPurpose
GET/notifications?limit&typeList notifications with unread counter
POST/notificationsCreate a notification (admin / system flows)
PATCH/notifications/:uid/readMark a single notification read
POST/notifications/read-allMark every notification read
DELETE/notifications/:uidDelete a notification

A WebSocket endpoint at wss://app.nfyio.com/api/ws pushes new notifications in real time when the dashboard is open. Bearer-token clients normally just poll GET /notifications.

Access Tokens

These are the same tokens you mint at Settings → Access Tokens. The endpoints let you manage them programmatically.

MethodPathPurpose
GET/access-tokens?teamUid=…List tokens. Token values are NOT returned — only metadata.
POST/access-tokensCreate a token. Body: { scope: "read"|"write", expireDays, description?, route?, teamUid }. Returns the full token value once.
GET / PUT / DELETE/access-tokens/:uidRead / update / revoke. Revoked tokens stop working on the next request.

Storage Access Keys (S3 credentials)

Manage the AWS-style key pairs used to talk to https://s3.nfyio.com. The S3 wire protocol itself is documented in Object Storage.

MethodPathPurpose
GET/object-storage/access-keys?page&limitList access keys in the workspace
GET/object-storage/access-keys/check-name?name=…Name availability
GET/object-storage/access-keys/expiredKeys past their expiration date
POST/object-storage/access-keysCreate a key. Body: { name, bucketUids: [...], permission: "read"|"read-write", expiresAt? }. Returns { accessKeyId, secretAccessKey } — secret only once.
POST/object-storage/access-keys/regenerateIssue a new secret. Body: { uid }
PUT/object-storage/access-keys/permissionsChange permission / bucket scope
DELETE/object-storage/access-keysRevoke. Body: { uid }

Firewall

Workspace-level allow / deny rules applied on top of access-token auth.

MethodPathPurpose
GET/firewall?teamUid=…List rules
POST/firewallCreate rule. Body: { teamUid, type: "ipv4"|"ipv6"|"hostname", action: "allow"|"deny", ipAddress, description? }
GET / PUT / DELETE/firewall/:uidRead / update status / delete

Logs

System-emitted transaction logs. Read-only for tokens; the writeable methods exist for admin tooling and require an admin context.

MethodPathPurpose
GET/logs?from&to&route&status&page&limitTail recent transaction logs
GET/logs/:idSingle log entry

Dashboard & analytics

MethodPathPurpose
GET/dashboard?range=7d|30d|90dKPI rollup + trends + top drivers + bucket preview + quota snapshot. Drives the dashboard view.

For raw analytics over a custom range:

MethodPathPurpose
GET/object-storage/analytics/overview?start&end&projectUidKPI rollup
GET/object-storage/analytics/trends?start&end&projectUid&limitDaily time-series
GET/object-storage/analytics/top-drivers?start&end&dimension&metric&limitTop contributors
GET/object-storage/analytics/anomalies?start&end&zScoreSpike detection
POST/object-storage/analytics/refreshForce-refresh aggregations
GET/object-storage/analytics/refresh/:runIdRefresh job progress

Billing

Plans, pricing, currencies (read-only)

MethodPathPurpose
GET/billing/available-plansPlans the workspace can switch into
GET/billing/plansAll published plans
GET/billing/plans/:uidPlan detail
GET/billing/pricingsPricing tiers
GET/billing/pricings/:uidPricing detail
POST/billing/pricings/log-viewTrack that a pricing card was viewed (UI analytics)
GET/billing/plan-featuresFeature catalog
GET/billing/currenciesSupported currencies

Subscription

MethodPathPurpose
GET/billing/subscriptionCurrent subscription state
POST/billing/subscriptionSubscribe to a plan. Body: { pricingUid, paymentProvider }
PUT/billing/subscriptionUpgrade / downgrade
DELETE/billing/subscriptionCancel at period end
POST/billing/subscription/resumeResume a cancelled subscription before period end

Payment methods

MethodPathPurpose
GET/billing/payment-methodCurrent default payment method
POST/billing/payment-methodAttach a method. Body: { paymentMethodId } (Stripe ID returned by your client SDK)
DELETE/billing/payment-methodDetach
POST/billing/setup-intentStripe Setup Intent (returns clientSecret) for use with Stripe Elements

Usage, quota, transactions

MethodPathPurpose
GET/billing/quotaCurrent plan limits + usage. Source-of-truth for the dashboard quota bars.
POST/billing/quota/refreshInvalidate the workspace’s quota cache and rebuild
GET/billing/usage?month=YYYY-MMAggregated billing usage records
GET/billing/usage/:uidSingle usage record
GET/billing/transactions?startDate&endDate&page&limitPaginated transactions for the usage page
GET/billing/accounts and /billing/accounts/:uidBilling account profile (address, tax id, etc.)

Free quota → overage. Stay within the plan limits and usage is free. Once you exceed any metered limit (api calls, embedding tokens, chat tokens, storage GB) the account is billed at the per-unit overage price; on free plans, overage may also pause new operations until you upgrade. Both rules surface as banners on the dashboard.

Feedback

Used by the in-product feedback form.

MethodPathPurpose
POST/feedbacksSubmit feedback
GET/feedbacksList user’s submitted feedbacks
PATCH/feedbacks/:uidUpdate fields
POST/feedbacks/:uid/completeMark resolved
DELETE/feedbacks/:uidDelete

Reference catalog

Mostly read-only catalog endpoints used by the dashboard’s pickers. Listed for completeness; treat as GET … / GET …/:uid.

  • /users, /users/:uid — users in workspace
  • /providers, /providers/:uid — payment / model providers
  • /services, /services/:uid — platform service registry
  • /products, /products/:uid — billable product definitions
  • /product-prices, /product-prices/:uid — pricing rows
  • /networkings, /networkings/:uid — bucket networking config
  • /payments, /payments/:uid — payment records

Each follows the same envelope and CRUD shape as the other resources above.

Rate limits

The backend currently enforces:

  • Per-token burst limit: ~100 req / 10 s per access token.
  • Per-IP global limit: ~600 req / min per source IP.

Exceeding either returns 429 with Retry-After. For high-volume integrations (bulk imports, batch reindexing), batch your operations or contact support to raise the limit.

OpenAPI

The full machine-readable spec is served at:

https://app.nfyio.com/api/docs/openapi.json

Drop it into Postman, Insomnia, or openapi-typescript to generate clients.