Fieldproxy REST API
Base URL
Each workspace lives in one region, and its API base is that region's host, for example https://api-india-1.fieldproxy.ai (India) or https://api-us-east-1.fieldproxy.ai (US East). To look it up from a workspace id, call POST https://api.fieldproxy.ai/auth/org and read settings.url from the response.
# Find your workspace's regional API base
curl -X POST https://api.fieldproxy.ai/auth/org \
-H "content-type: application/json" \
-d '{"orgid": "<workspace-id>"}'
# => settings.url, for example https://api-india-1.fieldproxy.aiAPI keys
Administrators create keys in the web app under Settings, Security, API keys. Create one key per system, so you can revoke one without breaking the others. The key is sent on every request:
x-api-key: <your-api-key>| Setting | Options |
|---|---|
| Name | A label saying which system uses the key. |
| Expiry | 24 hours, 7 days, 30 days, 90 days, 1 year, or never. |
| Operations | Any of Read (/api/read), Insert (/api/insert and CSV import), Update (/api/update) and Delete (/api/delete). |
| Only some tables | Optional allowlist. Off means every table the workspace API can reach; on means only the tables you pick. |
Keys are listed as active, expired or revoked, and an administrator can revoke any key at any time.
Endpoints
| Endpoint | Operation scope | What it does |
|---|---|---|
POST /api/read | Read | Reads the rows matching a condition from one table. |
POST /api/insert | Insert | Inserts rows into a table. The same scope allows CSV import. |
POST /api/update | Update | Updates the rows matching a condition; one call can change many rows. |
POST /api/delete | Delete | Deletes rows from a table. |
Conventions
- Every endpoint is
POSTwith a JSON body (content-type: application/json). tableNameis required on every call and must be letters, digits and underscores, not starting with a digit. With a table allowlist, it must be on the key's list.condition(read, update, delete) is a non-empty object of column-value pairs. All pairs must match (AND), each by equality. Operators, ranges, lists, LIKE patterns and null matching are not supported, and an empty condition is refused, so a call can never touch every row by accident.- Values are sent as parameters, never pasted into SQL, and are converted to the column's type by Postgres.
- Every success returns
rowCount,tableandtenant(your workspace id).
Read rows: POST /api/read
curl -X POST https://api-india-1.fieldproxy.ai/api/read \
-H "x-api-key: $FIELDPROXY_API_KEY" \
-H "content-type: application/json" \
-d '{"tableName": "your_table", "condition": {"id": 1}}'
# Reads the rows matching condition from one table{
"data": [
{ "id": 1, "name": "Gamma", "status": "open", "qty": 1,
"created_at": "2026-10-18T17:40:31.814Z", "updated_at": "2026-10-18T17:40:31.814Z" }
],
"rowCount": 1,
"table": "your_table",
"tenant": "<workspace-id>"
}Read returns every matching row with all of its columns. There is no paging, column selection or sort parameter (extra keys such as limit, offset, columns or orderBy are ignored), so make the condition specific. A test read of 5,001 matching rows came back in one response.
Insert rows: POST /api/insert
curl -X POST https://api-india-1.fieldproxy.ai/api/insert \
-H "x-api-key: $FIELDPROXY_API_KEY" \
-H "content-type: application/json" \
-d '{"tableName": "your_table",
"data": [
{"name": "Gamma", "status": "open", "qty": 1},
{"name": "Delta", "status": "closed", "qty": 9}
]}'
# 200
# {"message": "Successfully inserted 2 rows into your_table",
# "rowCount": 2, "table": "your_table", "tenant": "<workspace-id>"}datamust be a non-empty array of row objects, even for one row.- Every row must have the same keys as the first row; the column list is taken from the first row.
- All rows go in one INSERT, so it is all or nothing: if any row fails, none are inserted. A test insert of 5,001 rows in one call succeeded.
- Columns you leave out get their database defaults (ids, timestamps). The response does not return the new rows; read them back by a value you set.
Update rows: POST /api/update
curl -X POST https://api-india-1.fieldproxy.ai/api/update \
-H "x-api-key: $FIELDPROXY_API_KEY" \
-H "content-type: application/json" \
-d '{"tableName": "your_table",
"condition": {"status": "open"},
"data": {"status": "closed", "qty": 7}}'
# 200
# {"message": "Update successful", "rowCount": 1000,
# "table": "your_table", "tenant": "<workspace-id>"}
# No match: {"message": "Update affected 0 rows — condition matched no rows in this table.", "rowCount": 0, ...}conditionpicks the rows;datais one object of the columns to set on all of them.- One call can update many rows (a test call updated 1,000). A condition that matches nothing returns 200 with rowCount 0 and says so in message.
- Each changed row fires the workspace's automations (see below).
Delete rows: POST /api/delete
curl -X POST https://api-india-1.fieldproxy.ai/api/delete \
-H "x-api-key: $FIELDPROXY_API_KEY" \
-H "content-type: application/json" \
-d '{"tableName": "your_table", "condition": {"id": 2}}'
# 200
# {"message": "Delete successful", "rowCount": 1,
# "table": "your_table", "tenant": "<workspace-id>"}Deletes every row matching condition. As with update, no match returns 200 with rowCount 0.
CSV import
An Insert key also covers CSV import from the Fieldproxy app. For system-to-system loads, send the rows as JSON to /api/insert: it takes thousands of rows in one atomic call.
Errors
Errors are JSON with a message. Insert errors also say which table, the Postgres error code and that nothing was inserted.
| Status | When | Example message |
|---|---|---|
| 401 | No x-api-key header | Authentication required |
| 403 | Unknown key | Invalid token |
| 403 | Revoked key | API key has been revoked |
| 403 | Table not on the key's allowlist | API key is not authorized for table 'jobs' |
| 400 | Missing or bad tableName | tableName is required |
| 400 | Missing or empty condition (read, update, delete) | condition object is required |
| 400 | Insert: data missing or not a non-empty array | Missing or invalid 'tableName' or 'data' in request body |
| 400 | Update: data missing, empty or not an object | data object is required |
| 400 | Insert: unknown column, NOT NULL, wrong type, rows with different keys | Unknown column: column "nope" … does not exist |
| 500 | Read, update or delete: unknown column or a value the column can't hold | Read failed (with an error field) |
{
"pgCode": "23502",
"column": "name",
"table": "your_table",
"message": "Column 'name' is NOT NULL but received NULL",
"note": "No rows were inserted — a single multi-row INSERT is atomic. ...",
"tenant": "<workspace-id>"
}Rate limits
Responses carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers (the limit seen in testing was 60). When Remaining reaches 0, wait for the reset before sending more. Batch writes into arrays instead of one call per row.
REST writes trigger automations
Writes through the REST API go through the platform write path, so they fire the workspace's automations like a change made in the app: entity_event rules on created, updated and deleted rows, and on /api/update also status_transition (a field changed from one value to another) and field_threshold (a number crossed a line). An update whose condition matches many rows fans out one automation run per changed row. Direct database writes do not fire these triggers, which is one reason to use the REST API for integrations.
See webhooks and automations for the trigger and step reference, and /developers/openapi.json for an OpenAPI 3.1 description of these endpoints.
Safety notes
- Give each key only the operations and tables its system needs, and the shortest expiry that works.
- Store keys in a secret manager; never put them in a browser, a mobile app or a public repository.
- Revoke a key the moment a system is retired or a key may have leaked.
- For AI assistants, prefer the MCP server: its writes are proposed, confirmed by a person and undoable.
Checked against the Fieldproxy platform reference on October 18, 2026.
Get your own custom field service management within a day. Tailored to your workflows.
We set up a workspace on your own data and connect your AI or your systems on the call.
Get Demo