Overview
The Standard Time® Zapier integration exposes a REST API that the Zapier platform uses to build automated workflows between Standard Time® and thousands of other apps. The integration is bidirectional:
- Triggers — Standard Time® fires a webhook to Zapier whenever a record is created or updated (projects, tasks, time entries, expenses, users).
- Actions — Zapier calls Standard Time® endpoints to create or update records in response to events in other apps.
The API consists of 16 endpoints in total, grouped into five categories: authentication, webhook subscription management, sample data, dynamic dropdowns, and actions.
| Category | Endpoints | Purpose |
|---|---|---|
| Authentication | 1 | Validate API key credentials and return user identity |
| REST Hooks | 2 | Subscribe and unsubscribe Zapier webhook URLs |
| Sample Data | 1 | Return a sample record for Zapier trigger setup |
| Dynamic Dropdowns | 2 | Populate project and user pickers in Zapier's UI |
| Actions | 8 | Create and update projects, tasks, time entries, and expenses |
| Total | 14 |
Authentication
Every request to the Standard Time® Zapier API must include two HTTP headers identifying the account and proving ownership of a valid API key.
| Header | Value | Example |
|---|---|---|
X-ST-Customer-Id |
Your Standard Time® customer/account identifier | cust_abc123 |
X-ST-Api-Key |
Your Standard Time® API key (generated in-app) | st_Abc1234… |
API Key Format
Keys are prefixed with st_ followed by 32 random bytes encoded as URL-safe Base64. Example prefix shown in the app: st_Abc1234 (truncated for display). The full key is shown only once at generation time — Standard Time® stores only a SHA-256 hash and will never display the plaintext key again.
Fallback Authentication
If the two custom headers are absent, the authentication filter also accepts:
Authorization: Bearer {apiKey}HTTP header?apiKey={apiKey}query string parameter (last resort)
The custom headers are the recommended and required form for the Zapier integration.
Auth Failures
Invalid or missing credentials return HTTP 401 Unauthorized with an empty body. All other errors return HTTP 200 with a JSON body containing "Success": false and an error message.
Base URL & Routes
All endpoints share the following base path pattern:
{{bundle.authData.siteUrl}}/zapier/{action}
{{bundle.authData.siteUrl}}/zapier/{action}/{id}
The siteUrl is the URL of the customer's Standard Time® web installation — for example, https://mycompany.standardtime.com. It is collected once during Zapier authentication and stored in bundle.authData.siteUrl.
The route segment {action} is the endpoint name (e.g., TestAuth, CreateProject). The optional {id} segment carries a record GUID where required (e.g., the Unsubscribe endpoint).
Response Format
All successful action and query responses return JSON with the following envelope:
{
"Success": true,
"Data": { ... },
"ErrorResults": ""
}
Error responses (application-level) use the same envelope with Success: false:
{
"Success": false,
"Data": null,
"ErrorResults": "Human-readable error description"
}
All datetimes are ISO 8601 UTC strings (2025-06-01T14:30:00Z). All record identifiers are GUIDs in lowercase hyphenated format (d290f1ee-6c54-4b01-90e6-d701748f0851).
Auth Test Endpoint
Used by Zapier during the "Connect Account" step to verify that the provided credentials are valid and return identifying information about the authenticated user.
Request: No body. Authentication headers only.
Response:
{
"Success": true,
"Data": {
"userId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"username": "jsmith",
"email": "jsmith@example.com"
},
"ErrorResults": ""
}
Zapier displays the username and email fields to the user as confirmation that the correct account was connected.
REST Hook Endpoints
Standard Time® uses Zapier's REST Hook pattern for triggers. When a user activates a Zap, Zapier calls the Subscribe endpoint to register a callback URL. When the Zap is turned off or deleted, Zapier calls the Unsubscribe endpoint to deregister it.
Subscribe
Request body:
{
"hookUrl": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
"EventType": "project.created"
}
| Field | Type | Description | |
|---|---|---|---|
| hookUrl | string | required | The Zapier webhook URL to POST events to |
| EventType | string | required | One of the 10 event type keys listed in the Trigger Reference |
Response:
{
"Success": true,
"Id": "a3f2c1b0-d4e5-4f67-8901-23456789abcd",
"ErrorResults": ""
}
The Id is the subscription GUID. Zapier stores this and sends it back when unsubscribing.
Unsubscribe
{id} is the subscription GUID returned by Subscribe. No request body is required.
Response:
{ "Success": true, "ErrorResults": "" }
Sample Data Endpoint
Zapier calls this endpoint during trigger setup to show the user a sample record. This allows Zapier users to map fields from a Standard Time® event to fields in downstream apps without waiting for a real event to fire.
{eventType} is a URL-encoded event type string, such as project.created.
Response: A single sample record matching the schema of the event type. See the Webhook Payload Schemas section for field lists per event type.
{
"Success": true,
"Data": {
"id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"name": "Sample Project",
"description": "A sample project for Zapier setup",
"clientId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "Active",
"startDate": "2025-01-06",
"finishDate": "2025-03-28",
"created": "2025-01-06T08:00:00Z",
"modified": "2025-01-06T08:00:00Z"
},
"ErrorResults": ""
}
Dynamic Dropdown Endpoints
These endpoints power the project and user pickers inside Zapier's action configuration UI, allowing users to select records by name rather than typing raw GUIDs.
Get Projects
Returns all projects accessible to the authenticated user.
{
"Success": true,
"Data": [
{ "id": "d290f1ee-6c54-4b01-90e6-d701748f0851", "name": "Website Redesign" },
{ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "Factory Line 3 Audit" }
],
"ErrorResults": ""
}
Get Users
Returns all users in the account.
{
"Success": true,
"Data": [
{ "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "username": "jsmith", "name": "Jane Smith" },
{ "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "username": "mwilson", "name": "Mike Wilson" }
],
"ErrorResults": ""
}
Action Endpoints
Action endpoints let Zapier create or update records in Standard Time® in response to events in other apps. All action endpoints use POST. Update endpoints apply only the fields present and non-empty in the request body — omitted or blank fields are left unchanged.
Projects
Create Project
| Field | Type | Description | |
|---|---|---|---|
| Name | string | required | Project name |
| Description | string | optional | Project description |
| ClientId | GUID | optional | Client record identifier |
| Status | string | optional | e.g., Active, Inactive, Complete |
| StartDate | date | optional | ISO 8601 date, e.g., 2025-01-06 |
| FinishDate | date | optional | ISO 8601 date |
Update Project
Same fields as Create Project, plus:
| Field | Type | Description | |
|---|---|---|---|
| id | GUID | required | ID of the project to update |
| Name, Description, ClientId, Status, StartDate, FinishDate | optional | Any subset of fields to update; non-empty values only are applied |
Response (both endpoints):
{
"Success": true,
"Data": {
"id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"name": "Website Redesign",
"description": "Q1 redesign project",
"clientId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "Active",
"startDate": "2025-01-06",
"finishDate": "2025-03-28",
"created": "2025-01-06T08:00:00Z",
"modified": "2025-01-06T08:00:00Z"
},
"ErrorResults": ""
}
Tasks
Create Task
| Field | Type | Description | |
|---|---|---|---|
| Name | string | required | Task name |
| ProjectId | GUID | required | Parent project identifier |
| Description | string | optional | Task description |
| Status | string | optional | e.g., Active, Complete |
| StartDate | date | optional | ISO 8601 date |
| FinishDate | date | optional | ISO 8601 date |
| PercentComplete | integer | optional | 0–100 |
| AssignedUserIds | string | optional | Comma-separated list of user GUIDs to assign |
Update Task
Same fields as Create Task, plus:
| Field | Type | Description | |
|---|---|---|---|
| id | GUID | required | ID of the task to update |
| Name, ProjectId, Description, Status, StartDate, FinishDate, PercentComplete, AssignedUserIds | optional | Any subset; PercentComplete is applied only when > 0 |
Response (both endpoints):
{
"Success": true,
"Data": {
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"name": "Design Mockups",
"description": "Initial wireframes",
"projectId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"status": "Active",
"startDate": "2025-01-07",
"finishDate": "2025-01-21",
"percentComplete": 0,
"assignedUsers": ["f47ac10b-58cc-4372-a567-0e02b2c3d479"],
"created": "2025-01-07T09:00:00Z",
"modified": "2025-01-07T09:00:00Z"
},
"ErrorResults": ""
}
Time Entries
Create Time Entry
| Field | Type | Description | |
|---|---|---|---|
| ProjectId | GUID | required | Project this time entry is logged against |
| ProjectTaskId | GUID | optional | Task within the project |
| UserId | GUID | optional | User who logged the time; defaults to the authenticated user |
| StartTime | datetime | optional | ISO 8601 UTC datetime |
| EndTime | datetime | optional | ISO 8601 UTC datetime |
| Duration | integer | optional | Duration in minutes (used when StartTime/EndTime are not provided) |
| Description | string | optional | Work notes or memo |
Update Time Entry
Same fields as Create Time Entry, plus:
| Field | Type | Description | |
|---|---|---|---|
| id | GUID | required | ID of the time entry to update |
| ProjectId, ProjectTaskId, UserId, StartTime, EndTime, Duration, Description | optional | Any subset; Duration is applied only when > 0 |
Response (both endpoints):
{
"Success": true,
"Data": {
"id": "e5f6a7b8-c9d0-1234-efab-234567890123",
"projectId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"taskId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"userId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"startTime": "2025-01-08T13:00:00Z",
"endTime": "2025-01-08T15:30:00Z",
"duration": 150,
"description": "Completed wireframe review",
"created": "2025-01-08T15:30:00Z",
"modified": "2025-01-08T15:30:00Z"
},
"ErrorResults": ""
}
Expenses
Create Expense
| Field | Type | Description | |
|---|---|---|---|
| ProjectId | GUID | required | Project this expense is charged to |
| UserId | GUID | optional | User submitting the expense; defaults to the authenticated user |
| TypeId | GUID | optional | Expense category/type identifier |
| Amount | decimal | optional | Expense amount in account currency |
| StartDate | date | optional | ISO 8601 date the expense was incurred |
| Description | string | optional | Memo or receipt description |
Update Expense
Same fields as Create Expense, plus:
| Field | Type | Description | |
|---|---|---|---|
| id | GUID | required | ID of the expense to update |
| ProjectId, UserId, TypeId, Amount, StartDate, Description | optional | Any subset; Amount is applied only when > 0 |
Response (both endpoints):
{
"Success": true,
"Data": {
"id": "f6a7b8c9-d0e1-2345-fabc-345678901234",
"projectId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"userId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"typeId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"amount": 124.50,
"startDate": "2025-01-09",
"description": "Conference travel",
"created": "2025-01-09T10:00:00Z",
"modified": "2025-01-09T10:00:00Z"
},
"ErrorResults": ""
}
Trigger Reference
Standard Time® supports 10 REST Hook triggers — one for each combination of record type (project, task, time entry, expense, user) and event (created, updated). Each trigger uses the Subscribe/Unsubscribe endpoints above and fires a webhook payload to Zapier whenever the corresponding event occurs.
| Trigger Name | EventType | Fires when… |
|---|---|---|
| New Project | project.created | A project is created in Standard Time® |
| Updated Project | project.updated | A project's fields are modified |
| New Task | task.created | A task is created within a project |
| Updated Task | task.updated | A task's fields are modified |
| New Time Entry | timeentry.created | A time entry is logged |
| Updated Time Entry | timeentry.updated | A time entry is modified |
| New Expense | expense.created | An expense record is created |
| Updated Expense | expense.updated | An expense record is modified |
| New User | user.created | A user account is created |
| Updated User | user.updated | A user account's details are modified |
Webhook delivery is asynchronous and non-blocking — it does not delay the Standard Time® operation that caused it. Each webhook is delivered via HTTP POST to the registered hookUrl. If the subscriber URL is unreachable, Zapier handles retries according to its own retry policy.
Webhook Payload Schemas
Each webhook POST carries a JSON object. The event field identifies the trigger type; the remaining fields are the record's current state at the time of the event.
Project (created / updated)
{
"event": "project.created",
"id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"name": "Website Redesign",
"description": "Q1 redesign project",
"clientId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "Active",
"startDate": "2025-01-06",
"finishDate": "2025-03-28",
"created": "2025-01-06T08:00:00Z",
"modified": "2025-01-06T08:00:00Z"
}
Task (created / updated)
{
"event": "task.created",
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"name": "Design Mockups",
"description": "Initial wireframes",
"projectId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"status": "Active",
"startDate": "2025-01-07",
"finishDate": "2025-01-21",
"percentComplete": 0,
"assignedUsers": ["f47ac10b-58cc-4372-a567-0e02b2c3d479"],
"created": "2025-01-07T09:00:00Z",
"modified": "2025-01-07T09:00:00Z"
}
Time Entry (created / updated)
{
"event": "timeentry.created",
"id": "e5f6a7b8-c9d0-1234-efab-234567890123",
"projectId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"taskId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"userId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"startTime": "2025-01-08T13:00:00Z",
"endTime": "2025-01-08T15:30:00Z",
"duration": 150,
"description": "Wireframe review session",
"created": "2025-01-08T15:30:00Z",
"modified": "2025-01-08T15:30:00Z"
}
Expense (created / updated)
{
"event": "expense.created",
"id": "f6a7b8c9-d0e1-2345-fabc-345678901234",
"projectId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"userId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"typeId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"amount": 124.50,
"startDate": "2025-01-09",
"description": "Conference travel",
"created": "2025-01-09T10:00:00Z",
"modified": "2025-01-09T10:00:00Z"
}
User (created / updated)
{
"event": "user.created",
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"username": "mwilson",
"email": "mwilson@example.com",
"name": "Mike Wilson",
"created": "2025-01-10T08:00:00Z",
"modified": "2025-01-10T08:00:00Z"
}
Security Notes
- Keys stored as SHA-256 hashes only — Standard Time® never persists a plaintext API key. The hash is computed at generation time; the original value is displayed once to the user and discarded.
- One active key per user — Generating a new key automatically revokes all previous keys for that user account.
- Header-based auth — Credentials travel in request headers, not in URLs or query strings (query string is a last-resort fallback only).
- Tenant isolation — Webhook subscriptions and API keys are scoped to the individual user. A webhook fires only to subscriptions registered by the authenticated user; it cannot access or trigger another user's Zaps.
- HTTPS required — All communication must occur over HTTPS. Plain HTTP requests are rejected.
- No key retrieval — There is no endpoint that returns a plaintext API key. If a key is lost, generate a new one.
API Key Management (In-App)
API keys for the Zapier integration are managed inside Standard Time® — not through the Zapier dashboard. Navigate to Settings → Integrations → Zapier API Key to access the key management dialog.
Operations available in the dialog
| Action | Result |
|---|---|
| Generate New Key | Creates a new key and displays the full plaintext value once. Any existing active key is immediately revoked. Copy the key before closing the dialog — it cannot be retrieved again. |
| Revoke Key | Permanently deactivates the current key. Existing Zaps that use the revoked key will stop working immediately until reconfigured with a new key. |
| Set Trace Level | Controls the detail level written to the ZapierDebug audit log: 0 = off, 1 = errors only, 2 = warnings + errors, 3 = all activity. Use level 3 temporarily when diagnosing integration issues. |