REST API
Every VAIF Studio feature is an HTTP API at https://api.vaif.studio. The SDKs are wrappers around these routes, so any language can use them. The machine-readable spec is at https://api.vaif.studio/openapi.json.
Authentication
Section titled “Authentication”Send your project API key in the X-Vaif-Key header. To act as one of your app’s signed-in users, add their access token:
curl "https://api.vaif.studio/v1/data/$PROJECT_ID/posts" \ -H "X-Vaif-Key: vk_pub_..." \ -H "Authorization: Bearer $USER_ACCESS_TOKEN"Management routes, such as projects, schema changes and billing, take a console access token instead. See Access tokens.
Data API
Section titled “Data API”/v1/data/{projectId}/{table} serves every table. The project ID in the path must match the API key’s project. /generated/{table} is the older form of the same routes and is being retired; see Migrating from /generated to /v1/data.
| Method | Path | What it does |
|---|---|---|
| GET | /v1/data/{projectId}/{table} |
List rows |
| GET | /v1/data/{projectId}/{table}/{id} |
Get one row |
| POST | /v1/data/{projectId}/{table} |
Create a row, or upsert (below) |
| PATCH | /v1/data/{projectId}/{table}/{id} |
Update a row |
| DELETE | /v1/data/{projectId}/{table}/{id} |
Delete a row |
| POST, PATCH, DELETE | /v1/data/{projectId}/{table}/bulk |
Create, update or delete many rows |
| POST | /v1/data/{projectId}/{table}/query |
Query with a JSON body |
| GET | /v1/data/{projectId}/{table}/search |
Text search |
| GET | /v1/data/{projectId}/{table}/aggregate |
Count, sum, average, minimum or maximum |
List rows
Section titled “List rows”| Parameter | What it does |
|---|---|
select |
Columns, separated by commas, or * |
where |
A JSON filter: {"field":"status","operator":"eq","value":"active"}, or {"AND":[…]} or {"OR":[…]} of those |
orderBy, orderDir |
The columns to sort by, separated by commas, and asc or desc for each |
limit |
Rows to return: 50 by default, at most 1000. More answers 400 LIMIT_TOO_HIGH |
offset |
Rows to skip |
include |
Foreign-key columns to expand into the rows they reference, separated by commas |
The where operators are eq, neq, gt, gte, lt, lte, like, ilike and in.
curl -G "https://api.vaif.studio/v1/data/$PROJECT_ID/orders" \ -H "X-Vaif-Key: $VAIF_PUBLISHABLE_KEY" \ --data-urlencode 'where={"AND":[{"field":"status","operator":"eq","value":"paid"},{"field":"total","operator":"gte","value":100}]}' \ --data-urlencode 'orderBy=created_at' --data-urlencode 'orderDir=desc' \ --data-urlencode 'limit=20'Upsert
Section titled “Upsert”Add _upsert and _conflict_columns to a create:
{ "email": "alice@example.com", "name": "Alice", "_upsert": true, "_conflict_columns": ["email"] }Search and aggregate
Section titled “Search and aggregate”GET …/{table}/search?q=alice&fields=name,email&limit=10GET …/{table}/aggregate?fn=sum&column=amount&group_by=status, wherefniscount,sum,avg,minormax
Your app’s users
Section titled “Your app’s users”| Method | Path | What it does |
|---|---|---|
| POST | /projects/{projectId}/auth/signup |
Create a user |
| POST | /projects/{projectId}/auth/login |
Sign in with email and password |
| POST | /projects/{projectId}/auth/logout |
End every session the user has, on every device |
| GET | /projects/{projectId}/auth/me |
The signed-in user |
| POST | /projects/{projectId}/auth/refresh |
A new access token for the refresh token, which changes on every refresh |
| POST | /projects/{projectId}/auth/magic/send |
Email a sign-in link |
| POST | /projects/{projectId}/auth/forgot-password |
Email a password reset link |
| POST | /projects/{projectId}/auth/reset-password |
Set a new password with the link’s token |
| POST | /projects/{projectId}/auth/mfa/verify |
Finish a two-factor sign-in |
Apps on their own domain receive the refresh token in the response body; see Session management. See Authentication for two-factor enrollment, email verification and sessions.
Storage
Section titled “Storage”| Method | Path | What it does |
|---|---|---|
| POST | /storage/upload |
Upload a file |
| POST | /storage/upload-url |
Get a signed upload URL for { "key", "sizeBytes", "contentType" }. It accepts a PUT of exactly sizeBytes bytes, with that content type when one is given |
| POST | /storage/download-url |
Get a signed download URL |
| GET | /buckets/{bucketId}/files |
List files (prefix, maxKeys, continuationToken) |
| POST | /storage/files/delete-batch |
Delete files: { "bucketId", "keys": [...] } |
| POST | /storage/multipart/create |
Start a resumable upload |
Functions
Section titled “Functions”| Method | Path | What it does |
|---|---|---|
| POST | /functions/{functionIdOrName}/invoke |
Invoke a function |
| GET | /functions/project/{projectId} |
List a project’s functions (console access token) |
Errors and rate limits
Section titled “Errors and rate limits”Errors are JSON with a typed code, and a limited request gets 429 with Retry-After. See Error codes.