Files
FlockPal/docs/API_REFERENCE.md
T
blaisadmin 4a43a450f3
Deploy / deploy-dev (push) Has been skipped
Deploy / deploy-prod (push) Successful in 2m43s
Additional Genders
2026-06-17 22:04:42 -04:00

27 KiB

FlockPal API Reference

This document describes the HTTP API currently implemented in backend/src/app.ts.

Base URLs

  • Development frontend: http://localhost:3000
  • Development API: http://localhost:5000
  • Production API: use your configured BACKEND_URL

Authentication

Most protected endpoints use a bearer token:

Authorization: Bearer <token>

The current backend supports two token systems.

1. Browser session tokens

Browser session tokens are created after:

  • a successful magic-link sign-in
  • a successful OAuth sign-in with Google, Microsoft, or Apple

After sign-in, the backend redirects the browser back to the frontend with an auth_token query parameter. That auth_token is the browser session token.

Example redirect:

http://localhost:3000/?auth_token=YOUR_SESSION_TOKEN

The backend stores only a hash of the session token in the database. The raw token is returned to the client once when the session is created.

2. Integration tokens

Integration tokens are created by an authenticated browser-session user through:

  • GET /api/integration-tokens
  • POST /api/integration-tokens
  • DELETE /api/integration-tokens/:tokenId

These tokens are intended for automation tools such as n8n, scripts, and server-to-server use.

Integration tokens are:

  • workspace-scoped
  • tied to the creating user
  • returned in raw form only once at creation time
  • either read_only or read_write

Use them exactly like session tokens:

Authorization: Bearer flpt_...

Token behavior by endpoint type

Browser-session-only endpoints:

  • /api/auth/logout
  • /api/auth/session
  • /api/auth/switch-workspace
  • /api/workspaces
  • /api/integration-tokens

Endpoints that accept either browser session tokens or integration tokens:

  • /api/workspace
  • /api/workspace/members
  • /api/birds
  • /api/birds/:birdId/weights
  • /api/birds/:birdId/vet-visits
  • /api/birds/:birdId/medications

Read-only integration tokens can call read endpoints, but cannot call write endpoints.

If authentication is missing or invalid, the API returns:

{ "error": "Authentication required." }

Browser-session-only endpoints reject integration tokens with:

{
  "error": "This endpoint requires a browser session instead of an integration token."
}

Write endpoints reject read-only integration tokens with:

{
  "error": "That integration token is read-only."
}

How Browser auth_token Is Issued

FlockPal issues the browser bearer token on the backend after a successful passwordless sign-in. The client does not generate it.

  1. The client calls POST /api/auth/magic-link/request.
  2. The backend creates a short-lived magic-link token and emails it, or returns a preview URL in local development.
  3. The user opens the magic link.
  4. GET /api/auth/magic-link/verify validates the magic-link token, creates an auth session, and generates a new auth_token.
  5. The backend redirects to the frontend with auth_token in the query string.

Example redirect:

http://localhost:3000/?auth_token=YOUR_SESSION_TOKEN

OAuth flow

  1. The client sends the user to GET /api/auth/oauth/{provider}/start.
  2. The provider authenticates the user and redirects back to the backend callback.
  3. The backend callback creates an auth session and generates a new auth_token.
  4. The backend redirects to the frontend with auth_token in the query string.

Example redirect:

http://localhost:3000/?auth_token=YOUR_SESSION_TOKEN

How the browser token is used

After the frontend receives auth_token, it should store it and send it on authenticated requests:

Authorization: Bearer YOUR_SESSION_TOKEN

Integration tokens use the same bearer-token header format, but they are created separately and are not used for browser login.

Roles

Workspace roles used by protected endpoints:

  • owner
  • assistant
  • caregiver
  • viewer

Role requirements are called out per endpoint below. If the signed-in member lacks permission, the API returns:

{ "error": "You do not have permission for that action." }

Data Shapes

User

{
  "id": "uuid",
  "email": "person@example.com",
  "name": "Taylor",
  "createdAt": "2026-04-14T12:34:56.000Z"
}

Workspace

{
  "id": 1001,
  "name": "Home Flock",
  "workspaceType": "standard",
  "billingEmail": "billing@example.com",
  "billingPlan": "household_basic",
  "createdAt": "2026-04-14T12:34:56.000Z",
  "updatedAt": "2026-04-14T12:34:56.000Z"
}

Workspace Member

{
  "id": "uuid",
  "workspaceId": 1001,
  "userId": "uuid",
  "inviteEmail": "member@example.com",
  "name": "Alex",
  "role": "viewer",
  "acceptedAt": "2026-04-14T12:34:56.000Z",
  "createdAt": "2026-04-14T12:34:56.000Z"
}

Bird

{
  "id": "uuid",
  "workspaceId": 1001,
  "name": "Kiwi",
  "tagId": "FP-001",
  "species": "Cockatiel",
  "vetClinicName": "Avian Care Center",
  "vetClinicAddress": "123 Feather Lane, Raleigh, NC",
  "vetAccountNumber": "FP-1001",
  "vetDoctorName": "Dr. Rivera",
  "gender": "female_dna",
  "dateOfBirth": "2023-05-10",
  "gotchaDay": "2023-08-21",
  "chartColor": "#cb3a35",
  "photoDataUrl": null,
  "notifyOnDob": false,
  "notifyOnGotchaDay": true,
  "createdAt": "2026-04-14T12:34:56.000Z",
  "latestWeightGrams": 92,
  "latestRecordedOn": "2026-04-14"
}

Weight

{
  "id": "uuid",
  "birdId": "uuid",
  "weightGrams": 92,
  "recordedOn": "2026-04-14",
  "notes": "Morning check"
}

Vet Visit

{
  "id": "uuid",
  "birdId": "uuid",
  "visitedOn": "2026-04-14",
  "clinicName": "Avian Care Center",
  "reason": "Wellness exam",
  "notes": "Healthy"
}

Medication

{
  "id": "uuid",
  "birdId": "uuid",
  "name": "Meloxicam",
  "dosage": "0.05 mL",
  "frequency": "twice_daily",
  "doseSchedule": [
    {
      "key": "dose-1",
      "label": "Morning",
      "time": "08:00"
    },
    {
      "key": "dose-2",
      "label": "Evening",
      "time": "20:00"
    }
  ],
  "route": "Oral",
  "startDate": "2026-04-14",
  "endDate": null,
  "notes": "Give with food"
}

Medication Administration

{
  "id": "uuid",
  "medicationId": "uuid",
  "birdId": "uuid",
  "administeredOn": "2026-04-14",
  "administrationSlot": "dose-1",
  "status": "administered",
  "notes": null,
  "createdByUserId": "uuid",
  "createdAt": "2026-04-14T12:34:56.000Z"
}

Common Validation Rules

  • Dates use YYYY-MM-DD
  • workspaceType is standard or rescue
  • member role is owner, assistant, caregiver, or viewer
  • bird gender is unknown, male, female, male_dna, or female_dna; male and female indicate assumed sex
  • bird chartColor must be a #RRGGBB hex color
  • photoDataUrl must be a base64 data:image/... URL
  • weightGrams must be a positive number up to 10000

Validation failures return 400 with this shape:

{
  "error": "Invalid ... payload",
  "details": {}
}

Endpoints

Health

GET /api/health

Public readiness-compatible health check. Verifies backend dependencies.

Response 200:

{
  "ok": true,
  "service": "flockpal-backend",
  "status": "ready",
  "checkedAt": "2026-06-06T00:00:00.000Z",
  "dependencies": {
    "postgres": { "ok": true, "latencyMs": 3 },
    "redis": { "ok": true, "latencyMs": 4 }
  }
}

Response 503 when Postgres or Redis is unavailable.

GET /api/health/live

Public liveness check. Verifies the backend process is running without checking dependencies.

Response 200:

{
  "ok": true,
  "service": "flockpal-backend",
  "status": "live",
  "uptimeSeconds": 120,
  "checkedAt": "2026-06-06T00:00:00.000Z"
}

GET /api/health/ready

Public readiness check. Verifies the backend can reach Postgres and Redis.

Response 200 uses the same shape as GET /api/health; response 503 means at least one dependency failed.

Metrics

GET /api/metrics

Requires auth and an admin user. Returns lightweight in-memory process and request counters for the current backend process.

Response 200:

{
  "startedAt": "2026-05-01T00:00:00.000Z",
  "uptimeSeconds": 120,
  "requests": {
    "total": 10,
    "inFlight": 0,
    "errors": 0,
    "averageDurationMs": 12.5,
    "byStatus": { "2xx": 10 },
    "byRoute": { "GET /api/health": 10 }
  },
  "memory": {
    "rss": 0,
    "heapTotal": 0,
    "heapUsed": 0,
    "external": 0,
    "arrayBuffers": 0
  },
  "queues": {
    "birdMilestoneReminders": {
      "waiting": 0,
      "active": 0,
      "delayed": 0,
      "completed": 0,
      "failed": 0
    }
  }
}

Admin

PATCH /api/admin/rescue-workspaces/:workspaceId

Requires an admin user. Browser session tokens and admin-owned read_write integration tokens are accepted, so automation tools can approve or reject rescue claims after external validation.

Request body:

{
  "rescueVerificationStatus": "approved"
}

Allowed statuses are pending, approved, and rejected.

Authentication

GET /api/auth/providers

Public list of configured OAuth providers.

Response 200:

{
  "providers": [
    {
      "providerKey": "google",
      "displayName": "Google",
      "enabled": true
    }
  ]
}

POST /api/auth/register

Password registration is disabled.

Response 410:

{
  "error": "Password-based registration is disabled. Use a magic link or an identity provider."
}

POST /api/auth/login

Password sign-in is disabled.

Response 410:

{
  "error": "Password-based sign-in is disabled. Use a magic link or an identity provider."
}

POST /api/auth/magic-link/request

Starts a passwordless sign-in flow.

Request body:

{
  "email": "person@example.com",
  "name": "Taylor",
  "redirectTo": "http://localhost:3000"
}

Notes:

  • name is optional
  • redirectTo is optional and defaults to the frontend base URL
  • if email delivery is not configured, the API returns a preview URL instead

Response 202:

{
  "ok": true,
  "message": "If that address can sign in, a magic link is on the way.",
  "previewUrl": "http://localhost:5000/api/auth/magic-link/verify?token=...",
  "delivery": "preview"
}

curl example:

curl -X POST http://localhost:5000/api/auth/magic-link/request \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "person@example.com",
    "name": "Taylor",
    "redirectTo": "http://localhost:3000"
  }'

Local-development example response when SMTP is not configured:

{
  "ok": true,
  "message": "If that address can sign in, a magic link is on the way.",
  "previewUrl": "http://localhost:5000/api/auth/magic-link/verify?token=...",
  "delivery": "preview"
}

GET /api/auth/magic-link/verify?token=...

Consumes a single-use magic-link token, creates or loads the user, creates a session, and redirects to the frontend with auth_token in the query string.

Responses:

  • 302 redirect on success
  • 400 if the token is missing, invalid, or expired

If you are testing locally and received a previewUrl, open that URL in a browser or inspect the redirect target to capture the auth_token.

POST /api/auth/logout

Requires a browser session. Invalidates the current session.

Response 204 with no body.

GET /api/auth/session

Requires a browser session. Returns the current session context.

Response 200:

{
  "token": "raw-session-token",
  "session": {
    "user": {
      "id": "uuid",
      "email": "person@example.com",
      "name": "Taylor",
      "createdAt": "2026-04-14T12:34:56.000Z"
    },
    "activeWorkspace": {
      "id": 1001,
      "name": "Home Flock",
      "workspaceType": "standard",
      "billingEmail": null,
      "billingPlan": "household_basic",
      "createdAt": "2026-04-14T12:34:56.000Z",
      "updatedAt": "2026-04-14T12:34:56.000Z"
    },
    "activeMembership": {
      "id": "uuid",
      "workspaceId": 1001,
      "userId": "uuid",
      "inviteEmail": "person@example.com",
      "name": "Taylor",
      "role": "owner",
      "acceptedAt": "2026-04-14T12:34:56.000Z",
      "createdAt": "2026-04-14T12:34:56.000Z"
    },
    "workspaces": [],
    "providers": []
  }
}

curl example:

curl http://localhost:5000/api/auth/session \
  -H 'Authorization: Bearer YOUR_SESSION_TOKEN'

POST /api/auth/switch-workspace

Requires a browser session. Switches the session's active workspace.

Request body:

{
  "workspaceId": 1002
}

Response 200 returns the same shape as GET /api/auth/session.

curl example:

curl -X POST http://localhost:5000/api/auth/switch-workspace \
  -H 'Authorization: Bearer YOUR_SESSION_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "workspaceId": 1002
  }'

Possible errors:

  • 403 if the user is not a member of the requested workspace

GET /api/auth/oauth/{provider}/start

Starts an OAuth login flow and redirects to the external identity provider.

Path params:

  • provider: google, microsoft, or apple

Concrete examples:

  • /api/auth/oauth/google/start
  • /api/auth/oauth/microsoft/start
  • /api/auth/oauth/apple/start

Query params:

  • redirectTo optional frontend redirect target after successful login

Responses:

  • 302 redirect to provider on success
  • 404 for an unknown provider
  • 400 if the provider is not configured

Browser-oriented example:

http://localhost:5000/api/auth/oauth/google/start?redirectTo=http://localhost:3000

curl can show the initial redirect, but this flow is meant to complete in a browser:

curl -i "http://localhost:5000/api/auth/oauth/google/start?redirectTo=http://localhost:3000"

GET /api/auth/oauth/{provider}/callback

POST /api/auth/oauth/{provider}/callback

OAuth callback used by providers. On success, the backend redirects to the frontend with auth_token in the query string.

Path params:

  • provider: google, microsoft, or apple

Responses:

  • 302 redirect on success
  • 400 for missing or expired OAuth state
  • 404 for unknown provider

Workspaces

GET /api/workspaces

Requires a browser session. Lists the signed-in user's workspace memberships.

Response 200:

{
  "workspaces": []
}

POST /api/workspaces

Requires a browser session. Creates a new workspace and makes the current user its owner.

Request body:

{
  "name": "Home Flock",
  "workspaceType": "standard",
  "billingEmail": "billing@example.com",
  "billingPlan": "household_plus"
}

Notes:

  • workspaceType must be standard or rescue
  • billingPlan may be household_basic, household_plus, household_macaw, or household_hyacinth_macaw
  • rescue workspaces are forced to rescue_free

Response 201:

{
  "workspace": {}
}

GET /api/workspace

Requires auth. Returns the active workspace. Browser sessions and integration tokens can both use this endpoint.

Response 200:

{
  "workspace": {}
}

PUT /api/workspace

Requires auth with write access and role owner or assistant. Updates the active workspace.

Request body:

{
  "name": "Updated Flock",
  "workspaceType": "standard",
  "billingEmail": "billing@example.com",
  "billingPlan": "household_basic"
}

Response 200:

{
  "workspace": {}
}

DELETE /api/workspace

Requires a browser session and role owner. Deletes the active flock only when it has no birds.

Behavior:

  • if the flock still has birds, deletion is blocked
  • collaborators, sessions, and integration tokens tied to the flock are removed with it
  • the backend switches the user to another existing flock, or creates a new personal flock automatically if needed

Response 200:

{
  "deletedWorkspaceId": 1001,
  "token": "raw-session-token",
  "session": {}
}

Possible errors:

  • 409 if birds are still assigned to the flock
  • 404 if the flock no longer exists

GET /api/workspace/members

Requires auth. Lists members for the active workspace. Browser sessions and integration tokens can both use this endpoint.

Response 200:

{
  "members": []
}

POST /api/workspace/members

Requires auth with write access and role owner or assistant. Invites or upserts a workspace member.

Request body:

{
  "name": "Alex",
  "email": "alex@example.com",
  "role": "viewer"
}

Response 201:

{
  "member": {}
}

DELETE /api/workspace/members/:memberId

Requires auth with write access and role owner or assistant. Removes a non-owner member.

Response 204 with no body.

Possible errors:

  • 404 if the member was not found or is an owner

Birds

GET /api/birds

Requires auth. Lists birds in the active workspace. Browser sessions and integration tokens can both use this endpoint.

Response 200:

{
  "birds": []
}

POST /api/birds

Requires auth with write access and role owner, assistant, or caregiver. Creates a bird.

Request body:

{
  "name": "Kiwi",
  "tagId": "FP-001",
  "species": "Cockatiel",
  "vetClinicName": "Avian Care Center",
  "vetClinicAddress": "123 Feather Lane, Raleigh, NC",
  "vetAccountNumber": "FP-1001",
  "vetDoctorName": "Dr. Rivera",
  "gender": "female_dna",
  "dateOfBirth": "2023-05-10",
  "gotchaDay": "2023-08-21",
  "chartColor": "#cb3a35",
  "photoDataUrl": "",
  "notifyOnDob": false,
  "notifyOnGotchaDay": true
}

Notes:

  • dateOfBirth, gotchaDay, photoDataUrl, and veterinary info fields may be omitted or sent as empty strings
  • chartColor defaults to #cb3a35

Response 201:

{
  "bird": {}
}

Possible errors:

  • 409 if the workspace already uses that tagId

PUT /api/birds/:birdId

Requires auth with write access and role owner, assistant, or caregiver. Updates a bird.

Request body matches POST /api/birds.

Response 200:

{
  "bird": {}
}

Possible errors:

  • 404 if the bird does not exist in the active workspace
  • 409 if the workspace already uses that tagId

POST /api/birds/:birdId/transfer

Requires a browser session, write access, and role owner or assistant. Transfers a bird from the active flock to a flock owned by the provided receiving owner email. The sender does not need access to the receiving flock.

Request body:

{
  "destinationOwnerEmail": "new-owner@example.com"
}

Notes:

  • if the receiving owner email does not currently own a receiving flock, FlockPal creates a pending transfer, sends a bird-transfer invite, and returns 202; the bird stays in the sender's flock until the recipient signs in
  • pending transfers auto-complete when the recipient signs in; FlockPal creates or uses the recipient's personal flock as the receiving flock
  • immediate transfer requires the receiving owner email to match an accepted owner of exactly one other flock
  • when transferred, the bird keeps its existing weight and vet history because the record itself is reassigned

Response 200:

{
  "bird": {},
  "destinationOwnerEmail": "new-owner@example.com",
  "destinationWorkspace": {}
}

Response 202 when the receiving email does not currently own a receiving flock:

{
  "ok": true,
  "bird": {},
  "destinationOwnerEmail": "new-owner@example.com",
  "inviteSent": true,
  "invitePreviewUrl": "http://localhost:5000/api/auth/magic-link/verify?token=...",
  "inviteDelivery": "preview",
  "message": "A bird transfer invite was sent. The bird will stay in this flock until the recipient signs in, then FlockPal will automatically move it to their receiving flock."
}

Possible errors:

  • 400 if the payload is invalid
  • 404 if the bird is not in the active flock
  • 409 if that owner email owns more than one receiving flock
  • 409 if the destination flock already has a bird using the same tagId

POST /api/birds/:birdId/transfer-code

Requires a browser session, write access, and role owner or assistant. Creates a unique transfer code for a bird. Creating a new open code for the same bird revokes earlier unused codes for that bird.

Response 201:

{
  "transferCode": {
    "code": "secure-code",
    "bird": {}
  }
}

POST /api/bird-transfer-codes/:code/accept

Requires a browser session, write access, and role owner or assistant. Accepts a transfer code into the signed-in user's active flock.

Response 200:

{
  "bird": {},
  "sourceWorkspaceName": "Previous Flock",
  "workspace": {}
}

Possible errors:

  • 404 if the code does not exist, was revoked, was already used, or the bird is no longer available
  • 409 if the bird is already in the active flock or the active flock already has the same tagId

DELETE /api/birds/:birdId

Requires auth with write access and role owner, assistant, or caregiver. Deletes a bird.

Response 204 with no body.

Possible errors:

  • 404 if the bird does not exist in the active workspace

Weights

GET /api/birds/:birdId/weights

Requires auth. Lists weight entries for a bird in the active workspace.

Query params:

  • days optional, clamped to 1 through 425, default 30

Response 200:

{
  "weights": []
}

POST /api/birds/:birdId/weights

Requires auth with write access and role owner, assistant, or caregiver. Creates a weight entry.

Request body:

{
  "weightGrams": 92,
  "recordedOn": "2026-04-14",
  "notes": "Morning check"
}

Response 201:

{
  "weight": {}
}

Possible errors:

  • 404 if the bird does not exist in the active workspace
  • 409 if a weight already exists for that bird on that date

Vet Visits

GET /api/birds/:birdId/vet-visits

Requires auth. Lists vet visits for a bird in the active workspace.

Response 200:

{
  "vetVisits": []
}

POST /api/birds/:birdId/vet-visits

Requires auth with write access and role owner, assistant, or caregiver. Creates a vet visit.

Request body:

{
  "visitedOn": "2026-04-14",
  "clinicName": "Avian Care Center",
  "reason": "Wellness exam",
  "notes": "Healthy"
}

Response 201:

{
  "vetVisit": {}
}

Possible errors:

  • 404 if the bird does not exist in the active workspace

Medications

GET /api/birds/:birdId/medications

Requires auth. Lists medication records for a bird in the active workspace.

Response 200:

{
  "medications": []
}

POST /api/birds/:birdId/medications

Requires auth with write access and role owner, assistant, or caregiver. Creates a medication record.

Request body:

{
  "name": "Meloxicam",
  "dosage": "0.05 mL",
  "frequency": "twice_daily",
  "doseSchedule": [
    {
      "key": "dose-1",
      "label": "Morning",
      "time": "08:00"
    },
    {
      "key": "dose-2",
      "label": "Evening",
      "time": "20:00"
    }
  ],
  "route": "Oral",
  "startDate": "2026-04-14",
  "endDate": "",
  "notes": "Give with food"
}

Response 201:

{
  "medication": {}
}

PUT /api/birds/:birdId/medications/:medicationId

Requires auth with write access and role owner, assistant, or caregiver. Updates a medication record.

DELETE /api/birds/:birdId/medications/:medicationId

Requires auth with write access and role owner, assistant, or caregiver. Deletes a medication record.

GET /api/birds/:birdId/medication-administrations

Requires auth. Lists medication administration events for a bird in the active workspace.

Response 200:

{
  "administrations": []
}

POST /api/birds/:birdId/medications/:medicationId/administrations

Requires auth with write access and role owner, assistant, or caregiver. Upserts one scheduled medication event for a date and interval slot.

Request body:

{
  "administeredOn": "2026-04-14",
  "administrationSlot": "dose-1",
  "status": "administered",
  "notes": ""
}

status is administered or missed. administrationSlot identifies the interval event for that day, such as dose-1 or dose-2.

Medication frequency is one of once_daily, twice_daily, every_8_hours, every_6_hours, or as_needed. doseSchedule stores the editable labels and optional 24-hour HH:MM times used by administration slots.

Possible errors:

  • 400 if endDate is before startDate
  • 404 if the bird or medication does not exist in the active workspace

Integration Tokens

These endpoints are for browser-session users managing their own automation tokens. They are not accessible with an integration token itself.

GET /api/integration-tokens

Requires a browser session. Lists the current user's active integration tokens for the active workspace.

Response 200:

{
  "integrationTokens": [
    {
      "id": "uuid",
      "userId": "uuid",
      "workspaceId": 1001,
      "name": "n8n household sync",
      "tokenPrefix": "flpt_1234abcd56",
      "scope": "read_write",
      "lastUsedAt": "2026-04-14T12:34:56.000Z",
      "expiresAt": null,
      "revokedAt": null,
      "createdAt": "2026-04-14T12:00:00.000Z"
    }
  ]
}

POST /api/integration-tokens

Requires a browser session. Creates a new integration token for the active workspace and returns the raw token once.

Request body:

{
  "name": "n8n household sync",
  "scope": "read_write",
  "expiresInDays": 90
}

Notes:

  • scope may be read_only or read_write
  • expiresInDays is optional
  • the raw token is only returned at creation time

Response 201:

{
  "integrationToken": {
    "id": "uuid",
    "userId": "uuid",
    "workspaceId": 1001,
    "name": "n8n household sync",
    "tokenPrefix": "flpt_1234abcd56",
    "scope": "read_write",
    "lastUsedAt": null,
    "expiresAt": "2026-07-13T12:00:00.000Z",
    "revokedAt": null,
    "createdAt": "2026-04-14T12:00:00.000Z"
  },
  "token": "flpt_..."
}

curl example:

curl -X POST http://localhost:5000/api/integration-tokens \
  -H 'Authorization: Bearer YOUR_SESSION_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "n8n household sync",
    "scope": "read_write",
    "expiresInDays": 90
  }'

Use the returned token in your automation tool:

Authorization: Bearer flpt_...

DELETE /api/integration-tokens/:tokenId

Requires a browser session. Revokes an integration token owned by the current user in the active workspace.

Response 204 with no body.

Error Summary

Common status codes used by the API:

  • 200 successful read or update
  • 201 resource created
  • 202 async or queued success for magic-link requests
  • 204 successful delete or logout with no response body
  • 400 invalid request payload or expired callback state
  • 401 authentication required
  • 403 authenticated but not authorized for the action
  • 404 resource or provider not found
  • 409 uniqueness conflict
  • 410 password-based auth endpoints intentionally disabled

Source of Truth

This document reflects the routes currently implemented in:

  • backend/src/app.ts

If the docs and code ever disagree, treat the code as the source of truth.

Quick curl Workflow

Basic local-development auth check:

  1. Request a magic link:
curl -X POST http://localhost:5000/api/auth/magic-link/request \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "person@example.com",
    "name": "Taylor",
    "redirectTo": "http://localhost:3000"
  }'
  1. Copy the previewUrl from the response if local email is not configured.

  2. Open that URL in a browser and capture auth_token from the frontend redirect URL.

  3. Use the token:

curl http://localhost:5000/api/auth/session \
  -H 'Authorization: Bearer YOUR_SESSION_TOKEN'