Developers · Zapier integration

Zapier Integration API Reference

The LienDeadline Zapier integration calls these endpoints: OAuth 2.0 authorization, a connection test, two polling triggers, and the Create Deadline Project From Invoice action.

API base URL

https://secure-api-v1.liendeadline.com

Token, refresh, connection test, triggers and action

Authorization host

https://liendeadline.com

Browser step only: /api/zapier/oauth/authorize

Authentication

OAuth 2.0 authorization code with refresh tokens

JSON over HTTPS

Overview

The integration uses two hosts. The authorization request is a browser step on the website host, https://liendeadline.com, which receives the user’s LienDeadline sign-in session and forwards the request to the API. Every other request goes directly to the API host, https://secure-api-v1.liendeadline.com.

Use HTTPS for every request; the API host redirects plain-HTTP requests to HTTPS. Request and response bodies are JSON, and the token endpoint also accepts form-encoded bodies.

Data routes act on the LienDeadline user who authorized the connection. Every LienDeadline plan includes Zapier access.

MethodEndpointCredentialUsed for
GET/api/zapier/oauth/authorizeliendeadline.comLienDeadline sign-in sessionStart OAuth authorization in the user’s browser
POST/api/zapier/oauth/tokensecure-api-v1.liendeadline.comOAuth client ID and secretExchange an authorization code or a refresh token
POST/api/zapier/oauth/refreshsecure-api-v1.liendeadline.comOAuth client ID and secretRefresh tokens; same as the token endpoint with grant_type=refresh_token
GET/api/zapier/statussecure-api-v1.liendeadline.comBearer access tokenConnection test and connection label
GET/api/zapier/v2/triggers/upcomingsecure-api-v1.liendeadline.comBearer access tokenUpcoming Deadline trigger
GET/api/zapier/v2/triggers/reminderssecure-api-v1.liendeadline.comBearer access tokenDeadline Reminder trigger
POST/api/zapier/webhook/invoicesecure-api-v1.liendeadline.comBearer access tokenCreate Deadline Project From Invoice action

Authentication: OAuth 2.0

The integration uses the OAuth 2.0 authorization code grant with refresh tokens. The client secret is used only in server-to-server token requests. LienDeadline stores hashes of authorization codes, access tokens and refresh tokens, not the tokens themselves.

1. Authorization request

GEThttps://liendeadline.com/api/zapier/oauth/authorize

Zapier opens this URL in the user’s browser with these query parameters. Use the website host, not the API host: the LienDeadline sign-in session cookie is only sent to liendeadline.com, and the website forwards the request to the API with it.

ParameterRequiredDescription
response_typeYesMust be code.
client_idYesThe integration’s OAuth client ID.
redirect_uriYesWhere LienDeadline sends the result. It must be a Zapier OAuth callback URL (https://zapier.com/dashboard/auth/oauth/return/…, also accepted on www.zapier.com, or https://hooks.zapier.com/hooks/oauth/…) or a URI that LienDeadline has allowlisted.
stateNoReturned unchanged on the redirect to redirect_uri, including error redirects.
scopeNoStored with the grant and returned in the token response. The Zapier app sends zapier:read zapier:write.

If the user is signed in, LienDeadline issues an authorization code for that user and redirects to redirect_uri with code and state. There is no consent screen. The code can be used once and expires after 10 minutes by default.

If the user is not signed in, LienDeadline redirects to its sign-in page, https://liendeadline.com/auth/login, with the authorization URL in the next parameter. After sign-in, the browser returns to the authorization URL and LienDeadline redirects straight back to Zapier with the code.

Successful redirect
HTTP/1.1 307 Temporary Redirect
Location: REDIRECT_URI?code=AUTHORIZATION_CODE&state=STATE_FROM_REQUEST

A missing or unaccepted redirect_uri returns 400 with invalid_request as JSON, without a redirect. Other failures redirect to redirect_uri with error, error_description and state:

  • unsupported_response_type: response_type is not code.
  • unauthorized_client: the client_id is not recognized.
  • access_denied: the signed-in account has no matching LienDeadline profile, or its plan does not include Zapier access.

2. Token request

POSThttps://secure-api-v1.liendeadline.com/api/zapier/oauth/token

Exchange the authorization code for tokens, and later refresh them. This is a server-to-server request to the API host. Send parameters as application/x-www-form-urlencoded, as the Zapier app does, or as a JSON object with Content-Type: application/json. Authenticate the client with client_id and client_secret in the body or with HTTP Basic authentication; body values take precedence.

ParameterGrant typeDescription
grant_typeBothauthorization_code or refresh_token.
codeauthorization_codeThe code from the authorization redirect.
redirect_uriauthorization_codeMust match the redirect_uri sent in the authorization request.
refresh_tokenrefresh_tokenThe most recent refresh token issued to the connection.
client_idBothRequired unless sent with HTTP Basic authentication.
client_secretBothRequired unless sent with HTTP Basic authentication.
Exchange an authorization code
curl -X POST "https://secure-api-v1.liendeadline.com/api/zapier/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -H "Accept: application/json" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "code=AUTHORIZATION_CODE" \
  --data-urlencode "redirect_uri=REDIRECT_URI" \
  --data-urlencode "client_id=YOUR_CLIENT_ID" \
  --data-urlencode "client_secret=YOUR_CLIENT_SECRET"
Refresh tokens
curl -X POST "https://secure-api-v1.liendeadline.com/api/zapier/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -H "Accept: application/json" \
  --data-urlencode "grant_type=refresh_token" \
  --data-urlencode "refresh_token=REFRESH_TOKEN" \
  --data-urlencode "client_id=YOUR_CLIENT_ID" \
  --data-urlencode "client_secret=YOUR_CLIENT_SECRET"
200 response (both grant types)
{
  "access_token": "ACCESS_TOKEN",
  "token_type": "Bearer",
  "refresh_token": "REFRESH_TOKEN",
  "expires_in": 3600,
  "scope": "zapier:read zapier:write",
  "email": "ops@example.com"
}
FieldTypeDescription
access_tokenstringOpaque bearer token for the data routes.
token_typestringAlways Bearer.
refresh_tokenstringOpaque token for the next refresh. Every successful token request returns a new one.
expires_inintegerAccess-token lifetime in seconds; 3600 by default.
scopestringThe scope recorded at authorization, or an empty string.
emailstringEmail address of the LienDeadline account that authorized the connection.

Refresh alias

POSThttps://secure-api-v1.liendeadline.com/api/zapier/oauth/refresh

Accepts the same parameters and returns the same responses as the token endpoint, with grant_type set to refresh_token. The Zapier app refreshes through /api/zapier/oauth/token.

Token lifecycle

  • Access tokens expire after expires_in seconds. When a data route returns 401, the Zapier integration refreshes the access token automatically.
  • Refresh tokens are valid for 180 days by default and rotate: each successful refresh revokes the refresh token it used and returns a new one. A reused, revoked or expired refresh token returns invalid_grant.
  • Each LienDeadline user has one active Zapier access token. Issuing a new access token, by code exchange or by refresh, revokes the previous one.
  • Completing a new authorization also revokes the user’s earlier refresh tokens, so an older Zapier connection to the same LienDeadline user stops working until it is reconnected.

OAuth errors

The token and refresh endpoints return errors as JSON with error and error_description.

StatuserrorWhen
400invalid_requestA required parameter is missing: code or redirect_uri for authorization_code, or refresh_token for refresh_token. The authorization endpoint also returns it for a missing or unaccepted redirect_uri.
400invalid_grantThe authorization code is invalid, expired, already used or was issued for another redirect_uri, or the refresh token is invalid, expired or already used.
400unsupported_grant_typegrant_type is not authorization_code or refresh_token.
401invalid_clientThe client ID or client secret is missing or wrong. Client authentication is checked before the grant.
500server_errorOAuth is not configured on the server.
Error response
{
  "error": "invalid_grant",
  "error_description": "Invalid, expired, or already used authorization code."
}

Calling the data routes

Send the access token in the Authorization header. A missing, unknown, expired or revoked token returns 401 with {"detail": "Unauthorized"}.

Authorization: Bearer ACCESS_TOKEN

Connection test

Connection status

GEThttps://secure-api-v1.liendeadline.com/api/zapier/status

Zapier calls this route to test the connection and uses email as the connection label.

Request
curl "https://secure-api-v1.liendeadline.com/api/zapier/status" \
  -H "Authorization: Bearer ACCESS_TOKEN"
200 response
{
  "connected": true,
  "token_last4": "a1b2",
  "token_created_at": "2026-10-01T15:30:00+00:00",
  "auth_mode": "oauth2",
  "oauth_ready": true,
  "email": "ops@example.com"
}
FieldTypeDescription
connectedbooleantrue when the user has an active access token.
token_last4stringLast four characters of the active access token.
token_created_atstringISO 8601 time the active access token was issued.
auth_modestringAlways oauth2.
oauth_readybooleanAlways true.
emailstringEmail address of the LienDeadline account that authorized the connection.

Triggers

Both triggers are polling endpoints that return a top-level JSON array. They cover projects that belong to the connected LienDeadline user. Invoices imported from QuickBooks are included only after their project type is confirmed. Dates are calculated in UTC.

Query parameters

ParameterTypeDefaultDescription
limitinteger, 1–50050Maximum number of items returned.
days_aheadinteger, 1–36530 (upcoming), 14 (reminders)Window in days from today. Deadlines from today through today plus days_ahead are included.
sinceISO 8601 date-timeNoneOnly include projects updated at or after this time.

A value outside these ranges, or a since value that is not a date-time, returns 422.

Upcoming Deadline

GEThttps://secure-api-v1.liendeadline.com/api/zapier/v2/triggers/upcoming

Returns one item per project whose lien filing deadline falls inside the window, most recently updated projects first. deadline_date is the lien filing deadline.

Request
curl -G "https://secure-api-v1.liendeadline.com/api/zapier/v2/triggers/upcoming" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  --data-urlencode "limit=50" \
  --data-urlencode "days_ahead=30"

Deadline Reminder

GEThttps://secure-api-v1.liendeadline.com/api/zapier/v2/triggers/reminders

Returns an item when a project’s preliminary notice or lien filing deadline is exactly one of the project’s reminder days away (1, 7 or 30 days), most recently updated projects first. deadline_date is the deadline that matched.

Only projects with Zapier reminders turned on in LienDeadline are included. Projects created by the action start with Zapier reminders turned off. A reminder day larger than days_ahead never matches, so set days_ahead to 30 or more to receive 30-day reminders.

Trigger item fields

FieldTypeDescription
idstringDeduplication key: a 32-character hash of the trigger type, deadline type, project, deadline date, days remaining and the project’s last update time.
trigger_typestringupcoming_deadline or deadline_reminder.
account_idstring or nullLienDeadline account that owns the project.
project_idstringLienDeadline project ID.
project_namestringProject name, or an empty string.
customer_namestringClient name saved on the project, or an empty string.
statestringProject state, normally a two-letter code such as TX.
deadline_datestringDeadline date, YYYY-MM-DD.
days_until_deadlineintegerDays from today (UTC) to deadline_date.
source_updated_atstringISO 8601 time the project was last updated, or its creation time when no update is recorded.
updated_atstringSame value as source_updated_at.
deep_link_urlstringLink to the project in the LienDeadline dashboard. Opening it requires signing in.

Zapier skips items whose id it has already seen. Because the id includes the days remaining, an upcoming deadline gets a new id on each day it stays in the window, and editing a project also produces a new id. A reminder item appears only on the day its reminder is due.

200 response
[
  {
    "id": "0f1e2d3c4b5a69788796a5b4c3d2e1f0",
    "trigger_type": "upcoming_deadline",
    "account_id": "00000000-0000-4000-8000-000000000001",
    "project_id": "00000000-0000-4000-8000-000000000002",
    "project_name": "Example Warehouse Retrofit",
    "customer_name": "Example Supply Co.",
    "state": "TX",
    "deadline_date": "2027-01-15",
    "days_until_deadline": 103,
    "source_updated_at": "2026-10-01T15:30:00+00:00",
    "updated_at": "2026-10-01T15:30:00+00:00",
    "deep_link_url": "https://liendeadline.com/dashboard?project=00000000-0000-4000-8000-000000000002"
  }
]

Action: Create Deadline Project From Invoice

Create a deadline project

POSThttps://secure-api-v1.liendeadline.com/api/zapier/webhook/invoice

Calculates the preliminary notice and lien filing deadlines for an invoice and saves the result as a project in the connected LienDeadline account.

HeaderRequiredDescription
AuthorizationYesBearer ACCESS_TOKEN
Content-TypeYesapplication/json
X-Zapier-Event-IdNoIdempotency key. See Retries and duplicates below.
Body fieldTypeRequiredDescription
statestringYesTwo-letter code or full name of one of the 50 states or DC, in any letter case.
invoice_datestringYesYYYY-MM-DD or MM/DD/YYYY. Saved and returned as YYYY-MM-DD.
invoice_amount_centsintegerOne amountInvoice amount in cents, 0 or more. The Zapier action sends this field.
invoice_amountnumberOne amountInvoice amount in dollars, 0 or more. Used only when invoice_amount_cents is absent.
project_namestringNoProject name.
client_namestringNoClient name. Triggers return it as customer_name.
project_typestringNoCommercial (default) or Residential.
rolestringNoYour role on the project, such as supplier (default) or contractor.
notesstringNoNotes saved on the project.
invoice_numberstringNoSent by the Zapier action. The API does not currently save or return it.

The API ignores body fields not listed here. A missing state or invoice_date, a date in another format, or an invoice_amount_cents value that is negative or not a whole number returns 422. An unrecognized state name, a state code LienDeadline does not support (the error has code UNSUPPORTED_STATE), a negative invoice_amount, or a request without either amount field returns 400.

Request
curl -X POST "https://secure-api-v1.liendeadline.com/api/zapier/webhook/invoice" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Zapier-Event-Id: zapier-source-INV-1001" \
  -d '{
    "state": "TX",
    "invoice_date": "2026-09-15",
    "invoice_amount_cents": 499200,
    "project_name": "Example Warehouse Retrofit",
    "client_name": "Example Supply Co.",
    "project_type": "Commercial",
    "role": "supplier"
  }'
201 response
{
  "success": true,
  "version": "v1",
  "id": "00000000-0000-4000-8000-000000000002",
  "project_name": "Example Warehouse Retrofit",
  "invoice_date": "2026-09-15",
  "state": "TX",
  "invoice_amount": "4992.00",
  "invoice_amount_cents": 499200,
  "preliminary_deadline": "2026-11-15",
  "preliminary_deadline_days": 42,
  "lien_deadline": "2027-01-15",
  "lien_deadline_days": 103,
  "message": "Project created successfully"
}

Example values are synthetic. Dates show the format only and are not deadline guidance.

FieldTypeDescription
successbooleantrue when the project was created.
versionstringAlways v1.
idstringID of the new LienDeadline project.
project_namestringProject name, or an empty string.
invoice_datestringInvoice date, YYYY-MM-DD.
statestringTwo-letter state code.
invoice_amountstringAmount in dollars with two decimal places.
invoice_amount_centsintegerAmount in cents.
preliminary_deadlinestring or nullPreliminary notice deadline, YYYY-MM-DD, or null when none was calculated.
preliminary_deadline_daysinteger or nullDays from today to the preliminary notice deadline.
lien_deadlinestringLien filing deadline, YYYY-MM-DD.
lien_deadline_daysintegerDays from today to the lien filing deadline.
messagestringProject created successfully

Retries and duplicates

Send X-Zapier-Event-Id to make retries safe. LienDeadline records each value per user in the same transaction that saves the project. A later request from the same user with the same value creates nothing and returns 200 without the project ID or deadlines. If a request fails before the project is saved, for example at the plan limit, the value is not recorded and a retry can succeed.

The Zapier action sets this header from its Deduplication key input (dedupe_key) as zapier-source- followed by the key. Without a key, it uses an identifier from the Zapier run when one is available, or otherwise a hash of the request body. Map a value that identifies the source invoice, such as its record number in your accounting app.

200 response for a repeated X-Zapier-Event-Id
{
  "success": true,
  "version": "v1",
  "duplicate": true,
  "message": "Event already processed"
}

Plan limits

Each project the action creates counts as one protected item toward the account’s plan limit (see Pricing). When the limit is reached, the action creates nothing and returns 402. Repeated requests that return the duplicate response do not count.

402 response
{
  "success": false,
  "version": "v1",
  "code": "LIMIT_REACHED",
  "limit_type": "manual_calcs",
  "used": 3,
  "limit": 3,
  "plan": "free"
}

Errors & limits

These statuses apply to the connection test, trigger and action routes.

StatusMeaningResponse body
400Action only: unrecognized state name, unsupported state code (code UNSUPPORTED_STATE), negative invoice_amount, or no amount field.{"success": false, "version": "v1", "error": "…"}
401Missing, unknown, expired or revoked access token. The Zapier integration refreshes the token automatically.{"detail": "Unauthorized"}
402Action only: the plan’s protected-item limit is reached.code is LIMIT_REACHED; see Plan limits.
403Triggers and action: the account’s plan does not include Zapier access.code is PLAN_NOT_ALLOWED, inside detail for the triggers.
422Invalid query parameter or request body.{"detail": [{"loc": […], "msg": "…", "type": "…"}]}
429Rate limit exceeded; see Rate limits below. The response has no Retry-After header. Zapier treats 429 as throttling and retries later.{"error": "Rate limit exceeded: 10 per 1 minute"}
500The deadline could not be calculated for a supported state, or the project could not be saved.{"detail": "…"} or {"success": false, "version": "v1", "error": "…"}

Rate limits

RouteLimit
GET /api/zapier/v2/triggers/upcoming60 requests per minute
GET /api/zapier/v2/triggers/reminders60 requests per minute
POST /api/zapier/webhook/invoice10 requests per minute

Support

For integration questions or access problems, email support with the request path, the response status and body, and the approximate time of the request. Never send access tokens, refresh tokens or client secrets.