Partner API Customers and Projects #
This guide explains how customers and projects work in the Friday API, how they relate to each other, and how you use them when tracking time and staying in sync with webhooks.
Summary #
You will learn:
- What a customer and a project represent in Friday.
- Which endpoints list, fetch, and update them.
- How they connect to time records, timetrack reports, and webhook events.
Prerequisites #
- Plan: Timetracking (or higher). Customers and projects are included on the timetracking tier.
- Auth: An API key for the company, sent as
X-API-Keyon every request. - Base URL: Same as the rest of the API (see the Friday API Overview).
Concepts #
| Term | Meaning |
|——|———|
| Customer | A job or job site your company tracks. Employees can clock work against a customer. |
| Project | A subdivision under a customer for more granular time tracking (e.g. phases or locations). |
A project always belongs to exactly one customer. In list and detail responses, you will see the relationship reflected (for example, a project includes parent customer fields where applicable).
Typical flow #
- List or sync customers → GET /customers (paginated)
- Optionally list projects → GET /projects?customer_id=…
- Use IDs on clock-in → POST /time-records/clock-in with customer_id / project_id
- Stay in sync → Webhooks: customer. and project.
You do not create customers or projects through this API today; use the Friday product UI for setup, then read and update via the API as needed.
Listing customers #
GET /customers
Returns a paginated list. Optional query parameters:
| Parameter | Purpose |
|———–|———|
| page, per_page | Pagination (defaults: page 1, 25 per page, max 100 per page) |
| name | Case-insensitive partial match on name |
| is_disabled | "true" or "false" to filter by disabled flag |
Results are sorted by name.
Customer detail #
GET /customers/:customer_id
Returns one customer, including its projects, when the customer belongs to your API key’s company.
Updating a customer #
PATCH /customers/:customer_id
Partial update. Only name and is_disabled are supported. Send at least one field in the JSON body.
Listing projects #
GET /projects
Returns a paginated list. Optional query parameters:
| Parameter | Purpose |
|———–|———|
| page, per_page | Pagination |
| customer_id | Restrict to projects under that customer |
| name | Case-insensitive partial match |
| is_disabled | "true" or "false" |
Results are sorted by customer, then name.
Project detail #
GET /projects/:project_id
Returns one project, including parent customer details when applicable.
Updating a project #
PATCH /projects/:project_id
Partial update. Only name and is_disabled are supported.
Time records and timetrack #
- Clock-in accepts optional
customer_idandproject_id. Your company may require one or both depending on settings; the API returns400with a clear error if a required combination is missing or if the customer or project is disabled. - Time record filters can narrow history by customer or project where the API supports it (see the interactive docs for
GET /time-records). - Timetrack reports can include per-customer or per-project breakdowns using query flags such as
include_customer_reportsandinclude_project_reports(seeGET /timetrack/companyandGET /timetrack/employee/:employee_idin the API reference).
For a full walkthrough of labor reporting by customer and project, see the Job Costing guide.
Job geofencing: When the company uses location fences, clock-in and clock-out may require coordinates or return geofencing errors. Fences are resolved from the customer and project on the clock-in request, or from the active time record on clock-out. Full request fields, validation rules, and example errors are documented under Time Records in the OpenAPI reference (/time-records/clock-in and /time-records/clock-out).
Webhooks #
Customer lifecycle events use the customer. prefix; project events use project.. Both are described under Customers and projects in the Subscribing to Webhooks guide.
Common pitfalls #
- Disabled records: You cannot clock into a disabled customer or project; the API returns
400if you try. - Wrong company: All IDs are scoped to the company tied to your API key. A
404usually means the resource does not exist or is not visible to that key. - Pagination: For large directories, use
per_pageup to 100 and walkpageuntildatais empty or you reachtotal_pages.
Quick reference #
| Action | Method | Path |
|——–|——–|——|
| List customers | GET | /customers |
| Get customer | GET | /customers/:customer_id |
| Update customer | PATCH | /customers/:customer_id |
| List projects | GET | /projects |
| Get project | GET | /projects/:project_id |
| Update project | PATCH | /projects/:project_id |
For request and response schemas, use the interactive API documentation (sandbox).