workers first
IndustriesPricingSecurityFor ProvidersHow It Works
Sign InGet started freeBook a demo

Guides

  • Introduction
  • Authentication
  • Errors
  • Rate limits
  • Idempotency
  • Pagination
  • Scopes

API Reference

  • Organization
  • Members
  • Customers
  • Sites
  • Shifts
  • timesheets
  • invoices
  • Bookings
  • Webhooks

Webhooks

  • Events & signatures

Developers

API Documentation

A REST API to integrate external systems: sync members and customers, verify members who sign up publicly, read shifts and bookings, and subscribe to real-time webhook events.

Download OpenAPI specWebhooks

Introduction

The Public API lets you integrate external systems with your organization: sync members and customers, verify members who sign up publicly, read shifts and bookings, and subscribe to real-time webhook events.

It is a REST API over HTTPS. All requests and responses are JSON. Every endpoint is scoped to your organization — you can only ever read or write your own data.

Base URL: all endpoints are served under /api/v1. Download the machine-readable contract from the OpenAPI link at the top of this page.

Authentication

Authenticate every request with an API key as a bearer token in the Authorization header. Create keys in the Developer area of your organization portal.

Workers First

The all-in-one platform for organizations to manage their workforce, operations, and the people they serve.

support@keepworkersfirst.org

For Organizations

  • Book a Demo
  • Pricing
  • Security
  • Industries
  • Developers

For Providers

  • Join as Provider
  • Learn More

For Families

  • Create Account
  • Learn More

Company

  • About Us
  • Contact
© 2026 Workers First. All rights reserved.
Privacy PolicyTerms of ServiceAccessibility
Keys come in two modes. **Live keys** (
fcn_live_…
) act on your production data. **Test keys** (
fcn_test_…
) resolve to your sandbox organization, so you can build and test integrations against disposable demo data without touching production.

Keys are shown once at creation — store them securely. A key carries a fixed set of scopes; requests outside a key’s scopes are rejected with insufficient_scope.

Errors

Errors use standard HTTP status codes and a consistent body: { "error": { "code", "message", "details?" } }. The code is stable and safe to branch on; message is human-readable and may change.

Validation failures (400 invalid_request) include a details array of { path, message } entries pinpointing each offending field.

Every response carries an X-Request-Id header — include it when contacting support.

400 invalid_request — The request body, query, or path parameters failed validation. details lists each offending field.

401 invalid_api_key — The Authorization header is missing, malformed, or the key does not exist.

401 revoked_api_key — The key was revoked. Create a new key in the Developer portal.

401 expired_api_key — The key is past its expiry date (rolled keys expire 24 hours after rolling).

403 insufficient_scope — The key is valid but lacks the scope this endpoint requires.

403 module_not_enabled — The endpoint belongs to a module that is not active for this organization.

403 sandbox_unavailable — A test-mode key was used but the organization has no sandbox. Create one from the portal, then retry.

404 not_found — Unknown route, or the resource does not exist in your organization.

405 method_not_allowed — The path exists but not for this HTTP method. The Allow header lists valid methods.

409 idempotency_conflict — This Idempotency-Key was already used with a different request payload.

409 idempotency_in_progress — The original request with this Idempotency-Key is still processing. Retry shortly.

409 conflict — The request conflicts with the current state of the resource.

429 rate_limited — Rate limit exceeded. Honor Retry-After and the X-RateLimit-* headers.

500 internal_error — Something went wrong on our side. The X-Request-Id header identifies the request for support.

Rate limits

Requests are rate limited per key. Standard keys allow 120 requests per minute; a few expensive endpoints have a lower strict-tier limit.

Every authenticated response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (epoch seconds). When you exceed the limit you receive 429 rate_limited with a Retry-After header — back off until the window resets.

Idempotency

Safely retry write requests by sending an Idempotency-Key header (any unique string). If a request with the same key succeeds, replays within 24 hours return the original response with Idempotency-Replayed: true instead of performing the action again.

Reusing a key with a different request body returns 409 idempotency_conflict. A replay while the original is still in flight returns 409 idempotency_in_progress — retry shortly.

Pagination

List endpoints return { "data": [...], "has_more": boolean, "next_cursor": string | null }, newest first.

Pass ?limit= (1–100, default 25) to size a page. When has_more is true, pass next_cursor as ?cursor= to fetch the next page. Cursors are opaque — do not construct them yourself.

Scopes

Each key grants a set of scopes. A :write scope implies the matching :read scope. Grant the minimum a given integration needs.

members:read — List and read members.

members:write — Create, update, verify, and deactivate members.

customers:read — List and read customers and sites.

customers:write — Create and update customers and sites.

shifts:read — List and read shifts and their assignments.

timesheets:read — List and read timesheets (worked/billable time per assignment).

invoices:read — List and read invoices and their line items.

bookings:read — List and read bookings.

organization:read — Read your organization profile.

webhooks:read — List webhook endpoints and delivery history.

webhooks:write — Manage webhook endpoints, secrets, and redeliveries.

API Reference

Browse endpoints by resource.

Organization

1 endpoints

Members

6 endpoints

Customers

4 endpoints

Sites

4 endpoints

Shifts

3 endpoints

timesheets

2 endpoints

invoices

2 endpoints

Bookings

2 endpoints

Webhooks

10 endpoints

curl "https://YOUR-DOMAIN/api/v1/organization" \
  -H "Authorization: Bearer $API_KEY"
curl -X POST "https://YOUR-DOMAIN/api/v1/members" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: 6f9c1e2a-..." \
  -H "Content-Type: application/json" \
  -d '{"business_name":"Example Care Services"}'
{
  "error": {
    "code": "invalid_request",
    "message": "Invalid request body.",
    "details": [
      {
        "path": "body.capacity",
        "message": "Expected number, received string"
      }
    ]
  }
}