Teambridge External API (0.1.0)

Download OpenAPI specification:

External API for Teambridge platform.

Date-Time Format: All date-time fields in this API use ISO 8601 format with timezone information (YYYY-MM-DDTHH:MM:SSZ). Examples: 2025-06-05T09:00:00Z (UTC), 2025-06-05T09:00:00-07:00 (with timezone offset).

Authentication: This API uses OAuth 2.0 Client Credentials flow for authentication.

Filtering: The unified Collections API supports advanced filtering via query parameters. See the Collections (Unified API) section for full details.

Collections (Unified API)

Powerful generic endpoints for reading and writing any collection type. Works with all collections using field UUIDs. Query /fields first to discover the schema, then use these endpoints for flexible data access across all collection types (shifts, users, placements, locations, custom collections, etc.).

Filtering

The unified Collections API (/v1/collections/{collectionId}/records) supports powerful filtering via query parameters. You can filter records by adding query parameters in the format {fieldUUID}_{operator}={value}.

Supported Operators:

  • _is: Exact match (all field types) - default if no suffix provided
  • _contains: Partial text match (TEXT fields only)
  • _gt: Greater than (NUMBER, DATETIME fields)
  • _gte: Greater than or equal (NUMBER, DATETIME fields)
  • _lt: Less than (NUMBER, DATETIME fields)
  • _lte: Less than or equal (NUMBER, DATETIME fields)

Filtering Features:

  • Multiple filters: Up to 10 filters per request with implicit AND logic (all must match)
  • Default operator: Parameters without a suffix default to _is behavior
  • Multiple operators on same field: Allowed (e.g., age_gte=21&age_lte=65 for range queries)
  • Case-insensitive: TEXT and SELECT field matching is case-insensitive
  • Smart date handling: DATETIME fields support both date-only (2025-01-01) and full ISO 8601 format (2025-01-01T14:30:00Z)

Reserved Parameters: The following parameter names are reserved and cannot be used as filter bases: page, size, limit, offset.

Filtering Examples:

  • Single filter (exact match): ?550e8400-..._is=john@example.com
  • Default operator (no suffix): ?550e8400-...=john@example.com (equivalent to _is)
  • Partial text match: ?550e8400-..._contains=john
  • Date exact match: ?abc123-..._is=2025-12-01
  • Date range: ?abc123-..._gte=2025-01-01&abc123-..._lte=2025-12-31
  • Number range: ?age-uuid-..._gte=21&age-uuid-..._lte=65
  • Multiple fields: ?550e8400-..._is=john@example.com&7c9e6679-..._is=active
  • Mixed operators: ?name-uuid-..._contains=john&age-uuid-..._gte=21

List collections

Returns metadata about all collections for the account associated with the provided access token.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
{
  • "metadata": {
    },
  • "collections": [
    ]
}

Retrieve field metadata for a collection

Returns all field definitions for a collection, including field identifiers, names, types, write format hints, select options (for native selects), and linked collection IDs (for link-to-object fields). Use this endpoint to discover the schema before reading or writing records.

Authorizations:
OAuth2
path Parameters
collectionId
required
string <uuid>

Unique ID of the collection

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "error": null
}

List records in a collection

Returns a paginated list of records for a collection. Each record is represented as a map of field UUIDs to values. Use the /fields endpoint first to get field metadata (names, types, write format hints) to interpret the data.

Filtering Support: This endpoint supports filtering via query parameters in the format {fieldUUID}_{operator}={value}.

  • Up to 10 filters per request with implicit AND logic (all filters must match)
  • Use the /fields endpoint to discover field UUIDs
  • See the API description above for detailed filtering documentation and examples

Supported Operators by Field Type:

  • TEXT: _is (exact), _contains (partial match)
  • NUMBER: _is, _gt, _gte, _lt, _lte
  • DATETIME: _is, _gt, _gte, _lt, _lte
  • BOOLEAN: _is
  • SINGLE_SELECT/MULTI_SELECT: _is
  • Default: No suffix defaults to _is behavior

Filter Examples:

  • Filter by email: ?{email-field-uuid}_is=john@example.com
  • Filter by partial name: ?{name-field-uuid}_contains=john
  • Filter by date range: ?{date-field-uuid}_gte=2025-01-01&{date-field-uuid}_lte=2025-12-31
  • Filter by age range: ?{age-field-uuid}_gte=21&{age-field-uuid}_lte=65
  • Multiple filters: ?{field1-uuid}_is=value1&{field2-uuid}_contains=value2
Authorizations:
OAuth2
path Parameters
collectionId
required
string <uuid>

Unique ID of the collection

query Parameters
page
required
integer >= 0
Default: 0

Zero-based page index

size
required
integer [ 1 .. 50 ]
Default: 20

Number of records per page (maximum 50)

enriched
boolean
Default: false

Whether to include additional partner data in the response

Responses

Response samples

Content type
application/json
Example
{
  • "data": [
    ],
  • "error": null
}

Create a new record

Creates a new record in the collection. The request body should contain a map of field UUIDs to string values. Use the /fields endpoint to discover field IDs and their expected write formats (writeFormatHint).

Authorizations:
OAuth2
path Parameters
collectionId
required
string <uuid>

Unique ID of the collection

Request Body schema: application/json
required
required
object

Map of field UUIDs to string values. Keys are the field identifiers (UUIDs), values are the field values formatted according to the field's writeFormatHint.

Responses

Request samples

Content type
application/json
{
  • "data": {
    }
}

Response samples

Content type
application/json
{
  • "data": "Resource created with ID: 123e4567-e89b-12d3-a456-426614174000",
  • "error": null
}

Get a single record by ID

Returns a single record identified by its UUID. The record is represented as a map of field UUIDs to values. Use the /fields endpoint to get field metadata.

Authorizations:
OAuth2
path Parameters
collectionId
required
string <uuid>

Unique ID of the collection

recordId
required
string <uuid>

Unique ID of the record

query Parameters
enriched
boolean
Default: false

Whether to include additional partner data in the response

Responses

Response samples

Content type
application/json
Example
{
  • "data": {
    },
  • "error": null
}

Update an existing record

Updates an existing record. The request body should contain a map of field UUIDs to string values for the fields you want to update. Only include fields that need to be changed. Use the /fields endpoint to discover field IDs and write formats.

Authorizations:
OAuth2
path Parameters
collectionId
required
string <uuid>

Unique ID of the collection

recordId
required
string <uuid>

Unique ID of the record to update

Request Body schema: application/json
required
required
object

Map of field UUIDs to string values. Keys are the field identifiers (UUIDs), values are the field values formatted according to the field's writeFormatHint.

Responses

Request samples

Content type
application/json
{
  • "data": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": null
}

Documents

Endpoints for uploading and managing documents.

Upload a document

Uploads a document file with optional metadata for the authenticated account.

Important: This endpoint requires multipart/form-data content type for file upload.

Limits:

  • Maximum file size: 100MB
  • Maximum roles per document: 10

The request consists of two parts:

  • file: The document file to upload (required)
  • request: JSON metadata for the document (optional)
Authorizations:
OAuth2
Request Body schema: multipart/form-data
required
file
required
string <binary>

The document file to upload (max 100MB)

object (CreateDocumentRequest)

Responses

Response samples

Content type
application/json
{}

Utilities

Utility endpoints for timezone information and other general-purpose data.

Get supported timezones

Returns a list of all supported timezone identifiers, sorted alphabetically.

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
[
  • "America/Los_Angeles",
  • "America/New_York",
  • "Europe/London",
  • "Asia/Tokyo"
]

Mappings

Endpoints for managing external system mappings. Mappings link Teambridge records to entities in external systems (like Bullhorn, ADP, etc.) by storing the external provider code, external ID, and object type.

List all mappings for a record

Returns all external system mappings for a specific Teambridge record. Mappings link records to external system entities.

Authorizations:
OAuth2
query Parameters
recordId
required
string <uuid>

UUID of the Teambridge record to get mappings for

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "error": null
}

Create a new mapping

Creates a new mapping linking a Teambridge record to an external system entity. Each mapping associates a record with an external provider, external ID, and object type.

Authorizations:
OAuth2
Request Body schema: application/json
required
recordId
required
string <uuid>

ID of the record in Teambridge

providerCode
required
string

Code identifying the external provider

externalId
required
string

ID of the entity in the external system

externalObjectType
required
string

Type of the object in the external system

Responses

Request samples

Content type
application/json
{
  • "recordId": "550e8400-e29b-41d4-a716-446655440000",
  • "providerCode": "BULLHORN",
  • "externalId": "EXT-12345",
  • "externalObjectType": "Candidate"
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": null
}

Update an existing mapping

Updates the external ID for an existing mapping. This is useful when the external system ID changes but the mapping relationship should be preserved.

Authorizations:
OAuth2
path Parameters
mappingId
required
string <uuid>

UUID of the mapping to update

Request Body schema: application/json
required
externalId
required
string

New external ID for the mapping

Responses

Request samples

Content type
application/json
{
  • "externalId": "EXT-67890"
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": null
}

Delete a mapping

Deletes an external system mapping. This removes the link between a Teambridge record and an external system entity without affecting the underlying record.

Authorizations:
OAuth2
path Parameters
mappingId
required
string <uuid>

UUID of the mapping to delete

Responses

Webhooks Webhook

Subscribe to events in Teambridge to receive real-time notifications when your data changes.

Account owners: configure your webhook subscriptions inside Settings > Account | Outbound webhooks

Choose a publicly-accessible HTTPS endpoint where we should send events. Select the events to which you would like to subscribe.

When you save the webhook subscription, a modal will show you your HMAC secret. Store this somewhere safe. The secret key lets you validate that events published to your endpoint come from us. If you lose your secret, you can rotate it and receive a new one.

Security

All webhook requests include HMAC-SHA256 signatures for verification. The signature lets you know that this event came from Teambridge.

Request Headers:

  • X-Webhook-Signature: HMAC-SHA256 signature with sha256= prefix (e.g., sha256=abc123...)
  • X-Webhook-Timestamp: Unix timestamp in seconds (when the webhook was sent)
  • Content-Type: application/json

Signature Verification:

  1. Extract the X-Webhook-Timestamp and X-Webhook-Signature headers from the request
  2. Strip the sha256= prefix from the signature header
  3. Construct the signed payload: {timestamp}.{request_body} (use the raw request body string, not parsed JSON)
  4. Compute HMAC-SHA256 of the signed payload using your webhook secret
  5. Compare the computed signature with the provided signature using constant-time comparison
  6. Reject requests with timestamps more than 5 minutes old (prevents replay attacks)

Example Verification (Node.js):

First, check that the timestamp is recent (within 5 minutes):

const timestamp = request.headers['x-webhook-timestamp'];
const currentTime = Math.floor(Date.now() / 1000);

if (Math.abs(currentTime - timestamp) > 300) {
  throw new Error('Webhook timestamp too old');
}

Then, compute the expected signature and compare. Note that you must use the raw request body string, not parsed JSON:

const crypto = require('crypto');
const signatureHeader = request.headers['x-webhook-signature'];
const signature = signatureHeader.replace('sha256=', '');
const rawBody = request.rawBody;

const signedPayload = `${timestamp}.${rawBody}`;
const expectedSignature = crypto
  .createHmac('sha256', secret)
  .update(signedPayload)
  .digest('hex');

if (!crypto.timingSafeEqual(
  Buffer.from(signature),
  Buffer.from(expectedSignature)
)) {
  throw new Error('Invalid webhook signature');
}

Secret Management

  • All webhook subscriptions for an account share the same secret key
  • Secrets are only shown once when first created or rotated
  • During rotation, update your verification code with the new secret
  • Store secrets securely (environment variables, secret managers)

Consuming Webhooks

Best Practices:

  1. Respond quickly - Return 200 OK within 5 seconds to avoid retries
  2. Process asynchronously - Queue the webhook for background processing
  3. Verify signatures - Always validate the HMAC signature before processing
  4. Check timestamps - Reject old webhooks to prevent replay attacks
  5. Handle idempotently - Use event_id to deduplicate events
  6. Return appropriate status codes:
    • 200 OK - Webhook received and verified successfully
    • 400 Bad Request - Invalid signature or expired timestamp
    • 500 Internal Server Error - Processing error (will trigger retry)

Payload Versioning

The webhook payload format is versioned. The current version is 1.0 (see the version field in the payload).

  • Breaking changes will increment the version number
  • Non-breaking additions (new optional fields) do not change the version
  • Parse the version field to handle different payload formats
  • Version changes will be announced in advance via release notes

Retry Behavior

If your endpoint does not return 200 OK, Teambridge will retry the webhook

  • Maximum retry attempts: 5
  • Webhooks are marked as failed after all retries are exhausted
  • Contact support to replay failed webhooks if needed
Authorizations:
WebhookSignature
Request Body schema: application/json
required
version
required
string

Webhook payload version (current version is "1.0")

event_type
required
string

The type of event that triggered the webhook. Event types follow snake_case naming convention (e.g., shift_created, user_updated, location_deleted).

event_id
required
string <uuid>

Unique identifier for this webhook event. Use this for idempotent processing to prevent duplicate handling of the same event.

timestamp
required
string <date-time>

ISO 8601 timestamp when the event occurred

account_id
required
string <uuid>

The account ID where the event occurred

required
object

Responses

Request samples

Content type
application/json
Example
{
  • "version": "1.0",
  • "event_type": "shift_updated",
  • "event_id": "550e8400-e29b-41d4-a716-446655440000",
  • "timestamp": "2025-06-05T14:30:00Z",
  • "account_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  • "data": {
    }
}