Summary and recommendation
Fountain's REST API (base URL: https://api.fountain.com/v2) authenticates via API key passed as a Bearer token in the Authorization header.
Keys are account-scoped - there is no OAuth 2.0 or per-user token flow documented publicly.
The API is applicant-centric: core objects are applicants, funnels, and locations;
there are no user-provisioning endpoints and no SCIM 2.0 support.
Pagination is cursor-based (param: cursor, default page size: 20, max: 100);
offset-based pagination is not supported.
Rate limits exist but specific numeric thresholds are not publicly documented - production integrations must implement exponential backoff.
For teams building an identity graph, Fountain applicant records keyed on id, email, funnel_id, and location_id can serve as a hiring-stage node, but the absence of SCIM means internal user identity for recruiters and admins cannot be synced via standard IdP flows.
API quick reference
| Has user API | Yes |
| Auth method | API Key (Bearer token in Authorization header) |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | N/A |
Authentication
Auth method: API Key (Bearer token in Authorization header)
Setup steps
- Log in to your Fountain account as an admin.
- Navigate to Settings > Integrations > API.
- Generate an API key from the API Keys section.
- Include the key in all requests as: Authorization: Bearer
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string | Unique identifier for the applicant/worker. | system-generated | immutable | UUID format. |
| string | Applicant's email address. | required | optional | Used as primary identifier in many workflows. | |
| phone_number | string | Applicant's phone number. | optional | optional | E.164 format recommended. |
| first_name | string | Applicant's first name. | optional | optional | |
| last_name | string | Applicant's last name. | optional | optional | |
| state | string | Current stage/state of the applicant in the funnel. | system-set | writable via stage transitions | Reflects funnel stage name. |
| funnel_id | string | ID of the hiring funnel the applicant belongs to. | required | immutable | |
| location_id | string | ID of the location associated with the applicant. | optional | optional | |
| data | object | Custom field data collected during the application process. | optional | optional | Key-value pairs matching funnel-defined custom fields. |
| created_at | string (ISO 8601) | Timestamp when the applicant record was created. | system-generated | immutable | |
| updated_at | string (ISO 8601) | Timestamp of last update to the applicant record. | system-generated | system-updated | |
| source | string | Recruitment source for the applicant. | optional | optional | |
| rejected_at | string (ISO 8601) | Timestamp when applicant was rejected, if applicable. | null | system-set on rejection | |
| hired_at | string (ISO 8601) | Timestamp when applicant was marked as hired. | null | system-set on hire |
Core endpoints
List Applicants
- Method: GET
- URL:
https://api.fountain.com/v2/applicants - Watch out for: Results are scoped to a single funnel when funnel_id is provided; omitting it may return cross-funnel results depending on permissions.
Request example
GET /v2/applicants?funnel_id=abc123&cursor=xyz
Authorization: Bearer <api_key>
Response example
{
"applicants": [{"id":"apl_1","email":"user@example.com","state":"Stage 1"}],
"pagination": {"next_cursor": "abc456"}
}
Get Applicant
- Method: GET
- URL:
https://api.fountain.com/v2/applicants/{id} - Watch out for: Returns 404 if the applicant ID does not exist or is not accessible under the authenticated account.
Request example
GET /v2/applicants/apl_1
Authorization: Bearer <api_key>
Response example
{
"id": "apl_1",
"email": "user@example.com",
"first_name": "Jane",
"state": "Stage 2",
"funnel_id": "fnl_abc"
}
Create Applicant
- Method: POST
- URL:
https://api.fountain.com/v2/applicants - Watch out for: Duplicate email within the same funnel may result in an error or merge depending on account configuration.
Request example
POST /v2/applicants
Authorization: Bearer <api_key>
{
"email": "new@example.com",
"funnel_id": "fnl_abc",
"first_name": "John"
}
Response example
{
"id": "apl_2",
"email": "new@example.com",
"state": "New Applicant",
"created_at": "2024-01-15T10:00:00Z"
}
Update Applicant
- Method: PATCH
- URL:
https://api.fountain.com/v2/applicants/{id} - Watch out for: Custom field keys must match exactly the field slugs defined in the funnel configuration.
Request example
PATCH /v2/applicants/apl_2
Authorization: Bearer <api_key>
{
"data": {"custom_field_1": "value"}
}
Response example
{
"id": "apl_2",
"data": {"custom_field_1": "value"},
"updated_at": "2024-01-16T08:00:00Z"
}
Move Applicant to Stage
- Method: PATCH
- URL:
https://api.fountain.com/v2/applicants/{id}/transition - Watch out for: State name must match the exact stage name in the funnel; invalid stage names return a 422 error.
Request example
PATCH /v2/applicants/apl_2/transition
Authorization: Bearer <api_key>
{
"state": "Background Check"
}
Response example
{
"id": "apl_2",
"state": "Background Check",
"updated_at": "2024-01-16T09:00:00Z"
}
List Funnels
- Method: GET
- URL:
https://api.fountain.com/v2/funnels - Watch out for: Funnel IDs are required for most applicant operations; retrieve them here before creating applicants.
Request example
GET /v2/funnels
Authorization: Bearer <api_key>
Response example
{
"funnels": [{"id":"fnl_abc","title":"Warehouse Associate","location_id":"loc_1"}],
"pagination": {"next_cursor": null}
}
List Locations
- Method: GET
- URL:
https://api.fountain.com/v2/locations - Watch out for: Location IDs are used to scope funnels and applicants; ensure correct location mapping when creating records.
Request example
GET /v2/locations
Authorization: Bearer <api_key>
Response example
{
"locations": [{"id":"loc_1","name":"Chicago Warehouse","address":"123 Main St"}]
}
Get Webhook Events (List Webhooks)
- Method: GET
- URL:
https://api.fountain.com/v2/webhooks - Watch out for: Webhook management via API availability may vary; verify in the developer portal as UI-based configuration may be the primary method.
Request example
GET /v2/webhooks
Authorization: Bearer <api_key>
Response example
{
"webhooks": [{"id":"wh_1","url":"https://yourapp.com/hook","events":["applicant.created"]}]
}
Rate limits, pagination, and events
Rate limits: Fountain enforces rate limits on API requests; specific numeric limits are not publicly documented.
Rate-limit headers: Unknown
Retry-After header: Unknown
Rate-limit notes: Contact Fountain support or consult your contract for rate limit details specific to your plan.
Pagination method: cursor
Default page size: 20
Max page size: 100
Pagination pointer: cursor
Webhooks available: Yes
Webhook notes: Fountain supports webhooks to notify external systems of applicant lifecycle events. Webhooks can be configured in the Fountain dashboard under Settings > Integrations > Webhooks.
Alternative event strategy: Polling the List Applicants endpoint with updated_at filters can serve as a fallback if webhooks are not available on a given plan.
Webhook events: applicant.created, applicant.stage_changed, applicant.hired, applicant.rejected, applicant.updated
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: N/A
- Endpoint: Not documented
Limitations:
- Fountain does not offer a native SCIM 2.0 endpoint for user provisioning as of the latest available documentation.
- IdP-based SCIM provisioning (Okta, Entra ID, etc.) is not natively supported.
Common scenarios
Three integration patterns are well-supported by the v2 API.
To ingest applicants from an external job board: GET /v2/funnels to resolve funnel_id, then POST /v2/applicants with email, funnel_id, first_name, last_name, phone_number, and source.
Check for a duplicate email within the same funnel before creating - the API may return a conflict error rather than silently merging.
To advance applicants through hiring stages programmatically: GET /v2/applicants/{id} to confirm current state, then PATCH /v2/applicants/{id}/transition with the target stage name.
Stage names are funnel-specific, case-sensitive, and must exactly match labels configured in the Fountain UI - invalid names return a 422.
Subscribe to the applicant.stage_changed webhook to confirm transitions in downstream systems.
To sync hired applicants to an HRIS: configure a webhook for applicant.hired in Settings > Integrations > Webhooks, extract id, email, first_name, last_name, hired_at, and location_id from the payload, then call GET /v2/applicants/{id} to retrieve the full data object before posting to the HRIS onboarding API, since webhook payloads may omit custom fields.
Ingest applicant from external job board into Fountain funnel
- GET /v2/funnels to retrieve the target funnel_id for the relevant job.
- POST /v2/applicants with email, funnel_id, first_name, last_name, phone_number, and any source field.
- Store the returned applicant id for subsequent tracking or updates.
Watch out for: If the same email already exists in the funnel, the API may return a conflict error. Check for existing applicants with GET /v2/applicants?email=
Advance applicant through hiring stages programmatically
- GET /v2/applicants/{id} to confirm current state.
- PATCH /v2/applicants/{id}/transition with the target state name matching the exact funnel stage label.
- Listen for applicant.stage_changed webhook event to confirm the transition in downstream systems.
Watch out for: Stage names are funnel-specific and case-sensitive. Retrieve the funnel's stage list from the Fountain UI or funnel detail endpoint to avoid 422 errors.
Sync hired applicants to an HRIS
- Configure a webhook for the applicant.hired event in Fountain Settings > Integrations > Webhooks.
- On webhook receipt, extract applicant id, email, first_name, last_name, hired_at, and location_id from the payload.
- Call GET /v2/applicants/{id} to retrieve full applicant data including custom fields if needed.
- POST the enriched record to the HRIS onboarding API.
Watch out for: Webhook payloads may not include all custom data fields; a follow-up GET on the applicant record is recommended to retrieve the full data object before syncing to HRIS.
Why building this yourself is a trap
The primary API trap is scope mismatch: Fountain's API is designed around applicant lifecycle, not internal user management. Teams expecting to automate recruiter provisioning or extend an identity graph to cover Fountain's internal users will find no supported path - there are no user-management endpoints and no SCIM endpoint.
A second trap is custom field portability: the data object on applicant records uses field slugs defined per-funnel, not globally, so any integration consuming custom fields must be re-mapped for each funnel.
A third caveat applies to webhook reliability: the API reference notes that webhook management via API may vary and UI-based configuration may be the only reliable method - verify before building an automated webhook registration flow. Finally, the v1 API may still respond but is not recommended for new integrations; pin explicitly to v2.
Automate Fountain workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.