All docs

Push data with the API

Let your transport system, ERP, or shop send fresh rate tables to Formspring with the REST API or an AI agent.

Updated . 5 min read.

Your transport management system, ERP, or shop already knows the latest rates, zones, and stock. Push them into a Formspring data table whenever they change, so your forms always quote from current numbers. You can also let an AI agent manage tables with MCP tools.

Base URL: https://formspring.io/api/v1. Requests use a bearer token; see API authentication.

Token abilities

Ability Lets the token
data-tables:read List tables, read table details, and page through rows.
data-tables:write Create, rename, and delete tables, and push rows.

A token only ever sees the tables of its own workspace. Asking for another workspace's table answers 404.

1. Create a table

bash
curl -X POST https://formspring.io/api/v1/data-tables \
  -H "Authorization: Bearer your-api-token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Pallet rates 2026",
    "slug": "pallet_rates",
    "columns": ["max_kg", "price"]
  }'

You can add "rows": [...] to load the first rows in the same call. The response is the table: id, name, slug, columns, row_count, and pushable (true when you can push rows into it).

2. Replace the whole table

PUT swaps the complete contents in one step. Send it every time your system exports the full rate card. The same body always gives the same result, so a retry is safe.

bash
curl -X PUT https://formspring.io/api/v1/data-tables/TABLE_ID/rows \
  -H "Authorization: Bearer your-api-token" \
  -H "Content-Type: application/json" \
  -d '{
    "rows": [
      { "max_kg": 100, "price": 40 },
      { "max_kg": 500, "price": 90 },
      { "max_kg": 1000, "price": 150 }
    ]
  }'
  • Each row is an object keyed by column name. Cells can be text, numbers, or empty. A missing cell is stored blank.
  • Add "columns": ["max_kg", "price"] to change the columns as well. Without it, the table keeps its current columns.
  • Text is cleaned the same way as a CSV upload: "12.50" becomes the number 12.5, and "01234" stays text.
  • An empty "rows": [] clears the table.
  • If anything in the request is invalid, nothing changes and the old rows stay in place.

3. Update a few rows

POST updates the rows whose key column matches and adds the rest. Cells you leave out of an existing row keep their value.

bash
curl -X POST https://formspring.io/api/v1/data-tables/TABLE_ID/rows \
  -H "Authorization: Bearer your-api-token" \
  -H "Content-Type: application/json" \
  -d '{
    "key_column": "max_kg",
    "rows": [
      { "max_kg": 500, "price": 95 },
      { "max_kg": 2000, "price": 300 }
    ]
  }'

The response says how many rows were added and updated (table details abbreviated):

json
{ "data": { "row_count": 4 }, "meta": { "created": 1, "updated": 1 } }

The key column must exist, every pushed row needs a value in it, and a key may appear only once per request. Keys match the way formulas do: capital letters and spaces are ignored, numbers compare as numbers.

4. Read it back

bash
curl -H "Authorization: Bearer your-api-token" \
  "https://formspring.io/api/v1/data-tables/TABLE_ID/rows?per_page=100&page=1"

Pages hold up to 100 rows (50 by default). meta gives total and last_page. GET /data-tables lists your tables and GET /data-tables/TABLE_ID shows one with its columns and row count.

Rename or delete

bash
curl -X PATCH https://formspring.io/api/v1/data-tables/TABLE_ID \
  -H "Authorization: Bearer your-api-token" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Pallet rates 2027", "slug": "pallet_rates" }'

curl -X DELETE https://formspring.io/api/v1/data-tables/TABLE_ID \
  -H "Authorization: Bearer your-api-token"

Changing the slug means formulas that use the old one stop finding the table, so update the forms too. Delete answers 202 because the removal runs in the background.

Limits

Limit Value
Rows per table 5,000 (the table after an upsert counts too)
Columns per table 20
Request body 1 MB (larger requests answer 413)
Rows per page when reading 100
Push requests 10 per minute per token; other calls share the standard API limit. Responses carry X-RateLimit-* headers.

Errors

Status Meaning
403 The token is missing data-tables:read or data-tables:write.
404 No such table in this workspace.
409 The table refreshes from an API (see here), so it cannot be pushed to.
413 The request is larger than 1 MB. Split it into smaller pushes.
422 The request is invalid. The errors map names the field and says what to fix, for example an unknown column, a row that is not an object, or too many rows.

Manage tables with an AI agent

Agents connected to the MCP server can manage tables with the same abilities.

Tool Ability What it does
list_data_tables data-tables:read List your tables.
get_data_table data-tables:read Show one table with a page of rows.
create_data_table data-tables:write Create a table, optionally with first rows.
update_data_table data-tables:write Rename a table or change its slug.
replace_data_table_rows data-tables:write Replace the whole table in one step.
upsert_data_table_rows data-tables:write Update rows by a key column and add the rest.
delete_data_table data-tables:write Delete a table (runs in the background).
refresh_data_table data-tables:write Fetch an API-linked table again now (up to 6 a minute).

Example prompt: "Replace the rows of my pallet_rates table with this export, then show me the first five rows." The agent reads the result of each call, so invalid data is reported back instead of half-applied.