Skip to content

A mini app API: your server, n8n and Make read and change the tables

Updated

A visitor placed an order in the app. Your server heard about it through a webhook, did its part and now has to write the result into that same order: a file link and the status “Done”. That is what the data API is for: a key that lets your server, n8n or Make find rows in the app’s tables, add, update and delete them. A buyer with the screen open sees the updated order without reloading.

Getting started

  1. 1

    Publish the app

    The API works with the tables of a published app. A key belongs to one app and opens none of your other projects.

  2. 2

    Create a key

    The Data tab → Connect other services → the API tab. Name the key after whoever uses it (“n8n”, “warehouse”) and choose access: read and write, or read only. The key is shown once — we keep only its fingerprint.

  3. 3

    Check it with a first request

    GET /tables returns the app’s tables with their column keys. You need those keys in every other request, and the window fills a ready example with your own table.

  4. 4

    Wire up the scenario

    In n8n and Make it is an HTTP Request node with Header Auth. The API description for import is at https://apps.build-mini.app/api/v1/openapi.json — Postman and Insomnia read it too.

Example: update an order

curl -X PATCH https://apps.build-mini.app/api/v1/tables/orders/rows/ROW_ID \
  -H "Authorization: Bearer bma_…" \
  -H "Content-Type: application/json" \
  -d '{"data": {"status": "Done", "result_url": "https://…"}}'

Send only the columns that change; the rest stay as they were, and null clears a column. The reply is the whole row: id, table, data, visitor, createdAt and updatedAt.

The six API addresses

GET /tables
The app’s tables, their columns and write mode.
GET …/rows
A table’s rows, oldest first. Filter by a column with where[column]=value, pages with limit and cursor, only fresh ones with updatedSince.
GET …/rows/{id}
One row.
POST …/rows
Add a row. Into a personal table — saying whose it is.
PATCH …/rows/{id}
Update a row: only the columns you send change.
DELETE …/rows/{id}
Delete a row.

Webhooks and the API are two halves of one link

A webhook tells your service that something happened in the app: a form was sent, a row was added or changed, a payment went through. The API answers the opposite question — how the service changes something in the app. The way back used to be a single inbound address that could only add a row to one table. Now a row can be found, updated by id and deleted.

Edits made with a key don’t fire webhook events. Otherwise the scenario that updated an order would instantly get “row changed” about its own edit and loop.

A personal row stays personal

In “everyone writes their own” tables — orders, requests, carts — a visitor sees only their own rows. The API keeps it that way: an edit doesn’t change a row’s owner, and a new row in a personal table is created only with its owner named, for example {"platform": "telegram", "id": 123456789}. Without that the request is refused: nobody but you would ever see such a row.

You can see what each key does

Next to each key the API tab shows when it was used, how many requests there were and how the last refusal ended: a wrong key, a write with a read-only key, a typo in a column, too many requests. That line is the first place to look when a scenario “does nothing”.

When you need a Google Sheet, not a server

Submissions and orders can be copied into your own Google Sheet without a line of code: the table window in the Data panel → Copy new records to a Google Sheet. Create an empty sheet, give our service address editor rights, paste the link — and every new record is appended there within a minute, with a last column “Added” in Moscow time.

Your own columns, like “Called back”, can be added on the right, and ours can be moved: we find a column by its name and never erase anything. The copy works for personal tables too, because it reads nothing back. If Google refuses a row, retries go on for about an hour; then a red strip appears in the window, a message arrives in the bot, and the Retry button sends what didn’t arrive. Only the app’s owner can connect the copy.

The limits, stated plainly

  • The API changes the app’s records. Catalog rows typed in the editor — products, services, a schedule — are changed in the editor, from a phone inside the app, or through the AI assistant.
  • At most 300 requests a minute per key. Beyond that the server refuses and says in the Retry-After header how many seconds to wait.
  • A key opens every table of the app, buyers’ personal orders included. Keep it on a server or in n8n credentials, not in app code or a browser. If it leaks, press Revoke and services using it are refused at once.
  • The API works while the app is open: once the trial or the plan ends, requests with a key are refused until payment, just as visitors are.
  • The Google Sheet copy carries records made after it was connected. What was already in the table is exported with the Export button and pasted by hand.

Questions people ask

Does a mini app have a REST API?
Yes, every published app: https://apps.build-mini.app/api/v1, the key in an Authorization: Bearer header (or X-API-Key if a service can only do that), a JSON body. Six addresses: the table list, rows with a filter, one row, add, update, delete.
How do I connect an app to n8n or Make?
Both ways. From the app to the scenario — a webhook on a form, row or payment event. From the scenario to the app — an HTTP Request node to the API with a key. openapi.json imports into Postman and Insomnia, which makes building requests easier.
Can submissions go to a Google Sheet without a developer?
Yes: the table window turns on copying new records into your Google Sheet. You need an empty sheet, editor access for our service address and the link. Rows arrive within a minute.
Does the API cost extra?
No, keys are created on any plan and work while the trial or a plan is active. Rows added through the API count toward the plan’s record quota just like rows added from the app.

Connect the app to your own system

Publish the app, create a key in the API tab and run the first request — the window fills the example with your own table.

Open the builder