# Authentication (https://docs.baseloop.io/authentication) Send your organization API key as a bearer token. Every API key endpoint needs this header: ```bash Authorization: Bearer ``` Keys in the query string are not accepted. A missing or wrong key returns `401`. Webhooks are the exception: they take no key. See [Webhooks](/webhooks). ## Get the key [#get-the-key] In the app, open **Settings > API key**. Only organization admins can see, copy and rotate the key. ## What the key can read [#what-the-key-can-read] The key belongs to your organization, not to a person. It reads every workspace and table in the organization, private workspaces included. Workspace sharing settings do not apply to it, so changing who can see a workspace never breaks an integration. Treat the key like an admin password. ## Keep it on your server [#keep-it-on-your-server] Store the key in an environment variable and call Baseloop from your backend. Never put it in browser code, a mobile app or a public repository. For a website or dashboard, call Baseloop from a server route and send your page only the data it needs. The Try it panel in these docs sends the key from your browser and forgets it when you leave or reload the page. ## Rotate the key [#rotate-the-key] In **Settings > API key**, click **Rotate**, then **Rotate key** to confirm. The old key stops working right away and the new one is copied to your clipboard, so update your integrations straight after. ## What the key does not open [#what-the-key-does-not-open] The key works only with the endpoints in these docs. The CLI signs in with your own account instead; see [CLI](/cli). # CLI (https://docs.baseloop.io/cli) Use Baseloop from your terminal, or let Claude Code and Codex use it for you. `baseloop` is the command-line tool for Baseloop. It runs enrichment, manages workspaces, tables and rows, and gives coding agents like Claude Code and Codex a way to work in Baseloop. The CLI signs in with your own account, so it sees what you see in the app. It does not use the organization API key. ## Install [#install] macOS, Linux and WSL2: ```bash curl -fsSL https://app.baseloop.io/install-cli | bash ``` Windows (PowerShell): ```powershell irm https://app.baseloop.io/install-cli.ps1 | iex ``` The installer adds `baseloop` to your PATH, sets up Claude Code and Codex if it finds them, and signs you in. If a coding agent is installing it for you, give it the [install guide for agents](https://github.com/baseloop-hq/baseloop-cli/blob/main/install.md) instead: it downloads and checks the installer before running it. ## Sign in [#sign-in] ```bash baseloop auth login # Opens your browser baseloop auth login --device # For SSH hosts, cloud machines and containers baseloop auth status # Shows whether you are signed in ``` With `--device`, the terminal shows a short code and a link. Open the link in a browser on any device, check the code matches and approve. ## Use it [#use-it] ```bash baseloop me # Your user and organization baseloop tools list # Everything the CLI can do baseloop tools describe list_workspaces --json # Details of one tool baseloop tools call list_workspaces --input '{}' # Run a tool baseloop tools call list_tables --input '{"workspaceId":""}' baseloop commands # Every command ``` Add `--json` to any command for output that scripts can read: ```json { "ok": true, "data": {}, "summary": "Human-readable one-liner", "meta": {} } ``` On failure, `ok` is `false`, `error` holds a `code`, `message` and `hint`, and the command exits with a non-zero code. ## With Claude Code and Codex [#with-claude-code-and-codex] ```bash baseloop setup skills ``` This adds Baseloop to every coding agent it finds, so you can ask in plain language, like "find the CTOs of these companies". You can also add the plugin yourself: ```bash # Claude Code claude plugin marketplace add baseloop-hq/baseloop-gtm-plugin claude plugin install baseloop-gtm # Codex codex plugin marketplace add baseloop-hq/baseloop-gtm-plugin codex plugin add baseloop-gtm@baseloop-gtm-plugin ``` ## Updates [#updates] The CLI updates itself in the background. To update now, run `baseloop upgrade`. To turn automatic updates off, run `baseloop setup auto-update off`. ## Something wrong? [#something-wrong] ```bash baseloop doctor ``` It checks the install, your sign-in, the connection to Baseloop and the agent setup, and says what to fix. ## Uninstall [#uninstall] To remove the CLI completely, binary included, run the uninstall script. macOS, Linux and WSL2: ```bash curl -fsSL https://raw.githubusercontent.com/baseloop-hq/baseloop-cli/main/scripts/uninstall.sh | bash ``` Windows (PowerShell): ```powershell irm https://raw.githubusercontent.com/baseloop-hq/baseloop-cli/main/scripts/uninstall.ps1 | iex ``` Your sign-in is kept, so a reinstall starts signed in. To remove it as well, run `baseloop uninstall --purge` before the script. On its own, `baseloop uninstall` removes the PATH entry, the install state and the agent setup but leaves the binary in place; add `--dry-run` to see what it would remove. The source and full reference are on [GitHub](https://github.com/baseloop-hq/baseloop-cli). # Errors (https://docs.baseloop.io/errors) Every error has the same shape. Branch on the status code. API key endpoints return errors in one shape, whatever went wrong: ```json { "statusCode": 400, "error": "API Error", "message": "querystring/limit Number must be less than or equal to 100" } ``` `message` is written for people. Branch on `statusCode`, not on the message text. | Status | When | Example `message` | | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | `400` | A parameter or the body is invalid: a bad `limit` or `cursor`, an unknown column ID, an operator the column does not accept, or a filter over the limits. | `Invalid fieldId(s). Use GET /tables//schema to find valid field IDs for this table.` | | `401` | The API key is missing or wrong. | `Unauthorized` | | `402` | Your subscription is paused. | `Resume your subscription to use the public API.` | | `404` | The table does not exist or belongs to another organization. | `Table not found` | | `429` | Too many requests. See [Rate limits](/rate-limits). | `Too Many Requests` | | `500` | Something failed on our side. Safe to retry. | `Internal server error` | ## Webhook errors [#webhook-errors] [Webhooks](/webhooks) use the same three fields, but `error` names the problem, like `"Bad Request"` or `"Not Found"`: ```json { "statusCode": 400, "error": "Bad Request", "message": "Too many items. Maximum 500 per request." } ``` Do not retry a webhook request automatically after a `500` without checking the table: the rows may have been added. # Filtering rows (https://docs.baseloop.io/filtering-rows) Search rows by text and filter them by column values. ## Text search [#text-search] Both row endpoints search cell values, ignoring case: ```bash curl "https://api-v2.baseloop.io/v1/tables//rows?q=acme" \ -H "Authorization: Bearer " ``` An empty `q` is ignored. In `POST /rows/query` the search goes in `query` (or `q`). When both are sent, `query` wins, even when it is empty. ## Filters [#filters] Filters need `POST /tables/{tableId}/rows/query`. Each rule compares one column with a value: ```bash curl -X POST https://api-v2.baseloop.io/v1/tables//rows/query \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "limit": 100, "query": "acme", "filters": { "combinator": "and", "rules": [ { "fieldId": "", "operator": "contains", "value": "Acme" } ] } }' ``` * `fieldId` is a column ID from `GET /tables/{tableId}/schema`. An unknown ID returns `400`. * `combinator` is `"and"` (the default, every rule must match) or `"or"` (any rule). * `value` is left out for `null`, `notNull` and the run-status operators. ## Operators by column type [#operators-by-column-type] Each column type accepts its own operators. An operator the column does not accept returns `400`, and the message lists the ones it does. | Column type | Operators | | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | `text` | `=` `!=` `contains` `doesNotContain` `startsWith` `containsAnyOf` `doesNotContainAnyOf` `in` `notIn` | | `url`, `image`, `formula` | `=` `!=` `contains` `doesNotContain` `startsWith` `containsAnyOf` `doesNotContainAnyOf` | | `email`, `phone_number` | `=` `!=` `contains` `doesNotContain` `startsWith` | | `number` | `=` `!=` `>` `>=` `<` `<=` | | `date` | `=` `<` `>` `isDatePreset` `between` | | `boolean`, `member` | `=` `!=` | | `select` | `=` `!=` `in` `notIn` | | `multi_select` | `in` `notIn` | | `action`, `webhook` | `=` `!=` `contains` `doesNotContain` `startsWith` `hasError` `hasNoError` `hasNotRun` `runConditionNotMet` `isFound` `isNotFound` | `null` and `notNull` work on every column. `hasError`, `hasNoError`, `hasNotRun` and `runConditionNotMet` also work on any column that runs an action or AI, whatever its type. ## Values [#values] | Operator | Value | | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `containsAnyOf`, `doesNotContainAnyOf` | A list of up to 20 strings: `["acme", "globex"]`. Values past 20 are ignored. | | `in`, `notIn` | A list: `["customer", "prospect"]` | | `isDatePreset` | One of `today`, `tomorrow`, `yesterday`, `thisWeek`, `lastWeek`, `thisMonth`, `lastMonth`, `thisQuarter`, `lastQuarter`, `thisYear`, `lastYear`, `last7Days`, `last14Days`, `last30Days`, `last60Days`, `last90Days`, `last180Days`, `last365Days` | | `between` | `{ "start": "2026-01-01T00:00:00Z", "end": "2026-03-31T23:59:59Z" }` | | Everything else | Text, a number or `true`/`false` | Values that are not text are sent on as JSON text, and each value can be up to 1,000 characters. ## Groups [#groups] A rule can also be a group with its own `combinator` and `rules`. This reads as `company contains "Acme" AND (status = "customer" OR status = "prospect")`: ```json { "filters": { "combinator": "and", "rules": [ { "fieldId": "", "operator": "contains", "value": "Acme" }, { "combinator": "or", "rules": [ { "fieldId": "", "operator": "=", "value": "customer" }, { "fieldId": "", "operator": "=", "value": "prospect" } ] } ] } } ``` Filters allow 5 levels, counting the top level, so groups nest 4 deep. Each group holds up to 25 entries, and all groups together hold up to 100, where a nested group counts as one entry in its parent. # Introduction (https://docs.baseloop.io/) Read your Baseloop tables from your own code, and send rows into them. The Baseloop API gives your code the tables you see in the app. * **Read data** with an API key: list workspaces and tables, get a table's columns, and read, search or filter its rows. * **Send data in** through a table's webhook URL: post JSON and each object becomes a row. * **Work from the terminal** with the Baseloop CLI, on its own or inside Claude Code and Codex. The API key endpoints only read. They never create, change or delete anything. To add rows, use a [webhook](/webhooks). ## Base URL [#base-url] ```text https://api-v2.baseloop.io/v1 ``` ## Endpoints [#endpoints] | Method | Endpoint | What it does | | ------ | ------------------------------ | ------------------------------------ | | `GET` | `/workspaces` | List workspaces | | `GET` | `/tables` | List tables | | `GET` | `/tables/{tableId}/schema` | Get a table's columns | | `GET` | `/tables/{tableId}/rows` | List rows, with optional text search | | `POST` | `/tables/{tableId}/rows/query` | Search and filter rows | | `POST` | `/webhook/{id}` | Send rows to a table | ## For AI agents [#for-ai-agents] Every page is also available as Markdown. [llms.txt](https://docs.baseloop.io/llms.txt) lists all pages and [llms-full.txt](https://docs.baseloop.io/llms-full.txt) holds all of them in one file. The full API description is at [openapi.json](https://docs.baseloop.io/openapi.json). # Pagination (https://docs.baseloop.io/pagination) Page through rows with a cursor. Row endpoints return one page at a time, up to `limit` rows (100 by default and at most). Each page tells you whether there is another: ```json { "rows": [], "limit": 100, "nextCursor": "eyJ0eXBlIjoiY3JlYXRlZEF0RGVzYyIsLi4ufQ", "hasNextPage": true } ``` To get the next page, send the same request again with `nextCursor` as `cursor`: ```bash curl "https://api-v2.baseloop.io/v1/tables//rows?limit=100&cursor=" \ -H "Authorization: Bearer " ``` For `POST /rows/query`, put `cursor` in the body. Keep going until `hasNextPage` is `false`; on the last page `nextCursor` is `null`. ## Rules for cursors [#rules-for-cursors] * Treat a cursor as an opaque string. Do not read, build or change it. * Use a cursor only with the endpoint, search and filters that produced it. A cursor reused with a different search or filters returns `400`. * Responses have no total count. To know how many rows a table has, use `rowCount` from `GET /tables`. ## Order [#order] * Without search text or filter rules, both row endpoints return rows newest first. * With search text or filter rules, they return rows in a stable order by row ID. Custom sorting is not supported. # Quickstart (https://docs.baseloop.io/quickstart) Get your API key and read your first rows. ## 1. Get your API key [#1-get-your-api-key] In the app, open **Settings > API key** and copy the key. Only organization admins can see it; if you are not an admin, ask one. Keep the key on your server, for example in an environment variable: ```bash export BASELOOP_API_KEY="" ``` ## 2. Find your table [#2-find-your-table] ```bash curl https://api-v2.baseloop.io/v1/tables \ -H "Authorization: Bearer $BASELOOP_API_KEY" ``` ```json { "tables": [ { "id": "tableId", "name": "Prospects", "emoji": ":chart_with_upwards_trend:", "workspaceId": "workspaceId", "workspaceName": "Sales", "rowCount": 1000, "fieldCount": 12 } ], "total": 1 } ``` ## 3. Get its columns [#3-get-its-columns] Rows key their cells by column ID. The schema tells you which ID is which column. ```bash curl https://api-v2.baseloop.io/v1/tables//schema \ -H "Authorization: Bearer $BASELOOP_API_KEY" ``` ## 4. Read rows [#4-read-rows] ```bash curl "https://api-v2.baseloop.io/v1/tables//rows?limit=10" \ -H "Authorization: Bearer $BASELOOP_API_KEY" ``` ```json { "rows": [ { "id": "rowId", "tableId": "tableId", "createdAt": "2026-05-24T12:00:00.000Z", "updatedAt": "2026-05-24T12:30:00.000Z", "createdByUserId": "userId", "cells": { "fieldId": { "value": "Acme", "status": "success" } } } ], "limit": 10, "nextCursor": "eyJ0eXBlIjoiY3JlYXRlZEF0RGVzYyIsLi4ufQ", "hasNextPage": true } ``` ## 5. Read the whole table [#5-read-the-whole-table] This reads every row, 100 at a time, and names each cell by its column: ```ts const BASE_URL = 'https://api-v2.baseloop.io/v1' const headers = { Authorization: `Bearer ${process.env.BASELOOP_API_KEY}` } async function get(path: string) { for (;;) { const response = await fetch(`${BASE_URL}${path}`, { headers }) // Over the rate limit: wait as long as the API says, then try again if (response.status === 429) { const seconds = Number(response.headers.get('retry-after') ?? 10) await new Promise((resolve) => setTimeout(resolve, seconds * 1000)) continue } const body = await response.json() if (!response.ok) throw new Error(`${response.status}: ${body.message}`) return body } } export async function readTable(tableId: string) { const { fields } = await get(`/tables/${tableId}/schema`) // Two columns can share a label: the second one gets its ID added, so neither is lost const columnNames = new Map() for (const field of fields) { const taken = [...columnNames.values()].includes(field.label) columnNames.set(field.id, taken ? `${field.label} (${field.id})` : field.label) } const rows = [] let cursor: string | null = null do { const query = new URLSearchParams({ limit: '100', ...(cursor ? { cursor } : {}) }) const page = await get(`/tables/${tableId}/rows?${query}`) for (const row of page.rows) { rows.push( Object.fromEntries( Object.entries(row.cells as Record).map(([fieldId, cell]) => [ columnNames.get(fieldId) ?? fieldId, cell.value, ]) ) ) } cursor = page.nextCursor } while (cursor) return rows } ``` * Row reads are limited to 60 requests a minute, so this reads up to 6,000 rows a minute. On a bigger table, `get` waits whenever the API answers `429`, then carries on. * Long values arrive cut to 200 characters, with `isTruncated: true` on the cell. This example keeps the cut value. See [Rate limits](/rate-limits). ## Next [#next] * Narrow the rows with [search and filters](/filtering-rows). * Try any endpoint from your browser in the [API reference](/api-reference/workspaces/list-workspaces). * Send rows into a table with a [webhook](/webhooks). # Rate limits (https://docs.baseloop.io/rate-limits) How many requests you can send, and the size limits on each one. ## Requests [#requests] | Limit | Counted per | Applies to | | ------------ | ------------------ | --------------------------------------------- | | 300 a minute | Organization | Workspace, table and schema reads | | 60 a minute | Organization | Row reads: `GET /rows` and `POST /rows/query` | | 60 a minute | IP address and key | Requests with a missing or wrong API key | | 100 a second | IP address | Webhook requests | Row reads have a lower limit because they do more work. Going over a limit returns `429`. Wait a moment and retry, and spread row reads over the minute instead of sending them all at once. ## Size of each request [#size-of-each-request] | Limit | Value | | ---------------------------- | --------------------- | | Rows per page (`limit`) | 100, also the default | | Search text (`q` or `query`) | 100 characters | | Filter rules per group | 25 | | Filter rules in total | 100 | | Filter nesting | 5 levels | | Filter value | 1,000 characters | | Objects per webhook request | 500 | | Webhook request body | 1 MB | A request over a size limit returns `400` with a message saying which limit, except an oversized webhook body, which returns `413`. ## Long cell values [#long-cell-values] Row responses cut cell values to 200 characters to keep pages small. A cut cell says so: ```json { "value": "first 200 characters", "status": "success", "isTruncated": true, "valuePreview": "first 200 characters" } ``` # Webhooks (https://docs.baseloop.io/webhooks) Send rows into a table by posting JSON to its webhook URL. A webhook table has a URL that turns every JSON object you post into a new row. Use it to send data in from your own code, a form, or tools like Zapier, Make and n8n. ## Get the URL [#get-the-url] 1. In the app, click **Create** and pick **Inbound webhook**. This creates a table with a webhook column. 2. Open the menu of the webhook column and click **Copy URL**. The webhook comes with the table when you create it. An existing table cannot get one later. ## Send rows [#send-rows] Post one object: ```bash curl -X POST \ -H "Content-Type: application/json" \ -d '{ "email": "jane@acme.com", "firstName": "Jane", "company": "Acme" }' ``` Or several at once, as an array or under `data`: ```bash curl -X POST \ -H "Content-Type: application/json" \ -d '{ "data": [ { "email": "jane@acme.com" }, { "email": "sam@globex.com" } ] }' ``` Each object can have any keys, nested or not; none are required. The response confirms how many rows are on their way: ```json { "success": true, "message": "Processing 2 records" } ``` ## What happens next [#what-happens-next] * Each object becomes one row. Rows appear about 5 seconds after your last request; while requests keep arriving, it can take up to about 30 seconds. Check the table before sending again, or rows are added twice. * The webhook column keeps the whole object. * Map keys of the object to columns in the app, and those columns fill in for every new row. ## Limits [#limits] * Up to 500 objects and 1 MB per request. * Up to 100 requests a second. * Empty objects are skipped. A request with nothing left to add returns `400`. ## Keep the URL private [#keep-the-url-private] Webhooks take no API key: anyone with the URL can add rows to the table. Keep it out of browser code and public repositories, like a password. ## Check a URL [#check-a-url] A `HEAD` request to the URL returns `200` when the webhook exists, without adding a row. Some tools use this to test a URL before sending data. # List workspaces (https://docs.baseloop.io/api-reference/workspaces/list-workspaces) `GET https://api-v2.baseloop.io/v1/workspaces` Returns every workspace in your organization with its number of tables. ## Authentication Send your API key as a bearer token: `Authorization: Bearer `. Your organization API key, from Settings > API key in the app. ## Responses ### 200 Your workspaces. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "workspaces": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "tableCount": { "type": "integer", "description": "Tables in this workspace." } }, "required": [ "id", "name", "tableCount" ], "additionalProperties": false } }, "total": { "type": "integer" } }, "required": [ "workspaces", "total" ], "additionalProperties": false, "description": "Your workspaces." } ``` ### 400 A parameter is invalid. `message` says which. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "A parameter is invalid. `message` says which." } ``` ### 401 The API key is missing or wrong. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "The API key is missing or wrong." } ``` ### 402 The subscription is paused. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "The subscription is paused." } ``` ### 429 Too many requests. See "Rate limits". Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "Too many requests. See \"Rate limits\"." } ``` ### 500 Something failed on our side. Safe to retry. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "Something failed on our side. Safe to retry." } ``` ## Example request ```bash curl -X GET "https://api-v2.baseloop.io/v1/workspaces" \ -H "Authorization: Bearer " ``` # List tables (https://docs.baseloop.io/api-reference/tables/list-tables) `GET https://api-v2.baseloop.io/v1/tables` Returns the tables in your organization, or only those in one workspace. ## Authentication Send your API key as a bearer token: `Authorization: Bearer `. Your organization API key, from Settings > API key in the app. ## Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `workspaceId` | query | no | string | Only return tables in this workspace. | ## Responses ### 200 Your tables. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "tables": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Use it as `tableId` in the other table routes." }, "name": { "type": "string" }, "emoji": { "type": [ "string", "null" ], "description": "Emoji shortcode shown next to the name, like `:chart_with_upwards_trend:`." }, "workspaceId": { "type": "string" }, "workspaceName": { "type": "string" }, "rowCount": { "type": "integer" }, "fieldCount": { "type": "integer", "description": "Number of columns." } }, "required": [ "id", "name", "emoji", "workspaceId", "workspaceName", "rowCount", "fieldCount" ], "additionalProperties": false } }, "total": { "type": "integer" } }, "required": [ "tables", "total" ], "additionalProperties": false, "description": "Your tables." } ``` ### 400 A parameter is invalid. `message` says which. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "A parameter is invalid. `message` says which." } ``` ### 401 The API key is missing or wrong. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "The API key is missing or wrong." } ``` ### 402 The subscription is paused. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "The subscription is paused." } ``` ### 429 Too many requests. See "Rate limits". Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "Too many requests. See \"Rate limits\"." } ``` ### 500 Something failed on our side. Safe to retry. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "Something failed on our side. Safe to retry." } ``` ## Example request ```bash curl -X GET "https://api-v2.baseloop.io/v1/tables" \ -H "Authorization: Bearer " ``` # Get table columns (https://docs.baseloop.io/api-reference/tables/get-table-schema) `GET https://api-v2.baseloop.io/v1/tables/{tableId}/schema` Returns the columns of a table. Row cells are keyed by column ID, so use this to put names on them. AI prompts, action settings and credentials are never included. ## Authentication Send your API key as a bearer token: `Authorization: Bearer `. Your organization API key, from Settings > API key in the app. ## Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `tableId` | path | yes | string | Table ID from `GET /tables`. | ## Responses ### 200 The table and its columns. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "table": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" } }, "required": [ "id", "name" ], "additionalProperties": false }, "fields": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Row cells are keyed by this ID." }, "name": { "type": "string", "description": "Internal column name." }, "label": { "type": "string", "description": "Column name shown in the app." }, "type": { "type": "string", "description": "Column type: text, number, boolean, date, email, phone_number, url, image, select, multi_select, object, formula, action, webhook, member or input." }, "options": { "type": [ "array", "null" ], "items": { "type": "object", "properties": { "label": { "type": "string" }, "value": { "type": "string" } }, "required": [ "label", "value" ], "additionalProperties": false }, "description": "Choices of a select or multi_select column, otherwise null." }, "isSystem": { "type": "boolean", "description": "True for columns Baseloop adds, like the creation date." } }, "required": [ "id", "name", "label", "type", "options", "isSystem" ], "additionalProperties": false } } }, "required": [ "table", "fields" ], "additionalProperties": false, "description": "The table and its columns." } ``` ### 400 A parameter is invalid. `message` says which. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "A parameter is invalid. `message` says which." } ``` ### 401 The API key is missing or wrong. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "The API key is missing or wrong." } ``` ### 402 The subscription is paused. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "The subscription is paused." } ``` ### 404 No table with this ID in your organization. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "No table with this ID in your organization." } ``` ### 429 Too many requests. See "Rate limits". Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "Too many requests. See \"Rate limits\"." } ``` ### 500 Something failed on our side. Safe to retry. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "Something failed on our side. Safe to retry." } ``` ## Example request ```bash curl -X GET "https://api-v2.baseloop.io/v1/tables//schema" \ -H "Authorization: Bearer " ``` # List rows (https://docs.baseloop.io/api-reference/rows/list-rows) `GET https://api-v2.baseloop.io/v1/tables/{tableId}/rows` Returns rows newest first, one page at a time. Add q to keep only rows whose cells contain that text. For column filters, use POST /tables/{tableId}/rows/query. ## Authentication Send your API key as a bearer token: `Authorization: Bearer `. Your organization API key, from Settings > API key in the app. ## Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `limit` | query | no | integer | Rows per page, 1 to 100. Default 100. | | `cursor` | query | no | string | `nextCursor` from the previous page. Only valid with the same search and filters. | | `q` | query | no | string | Case-insensitive text search across the row's cells, up to 100 characters. An empty value is ignored. | | `tableId` | path | yes | string | Table ID from `GET /tables`. | ## Responses ### 200 One page of rows. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "rows": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "tableId": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" }, "createdByUserId": { "type": [ "string", "null" ], "description": "ID of the member who added the row, when known." }, "cells": { "type": "object", "additionalProperties": { "type": "object", "properties": { "value": { "description": "The cell value: text, number, boolean, object or array depending on the column. null when empty." }, "status": { "description": "How the value got there. manual: entered by a person or sent in. success: an action produced it. failed: the action errored (see errorMessage). skipped or stopped: the action did not run. queued, waiting or running: the action is not done yet. null when not set." }, "isTruncated": { "type": "boolean", "description": "Present and true when the value was cut to 200 characters." }, "valuePreview": { "type": "string", "description": "The first 200 characters, when the value was cut." }, "errorMessage": { "description": "Why the cell failed, when it did." } }, "additionalProperties": false }, "description": "Cells keyed by column ID. Empty cells are left out. Get column names from the schema route." } }, "required": [ "id", "tableId", "createdAt", "updatedAt", "createdByUserId", "cells" ], "additionalProperties": false } }, "limit": { "type": "integer" }, "nextCursor": { "type": [ "string", "null" ], "description": "Pass it as `cursor` to get the next page. null on the last page." }, "hasNextPage": { "type": "boolean" } }, "required": [ "rows", "limit", "nextCursor", "hasNextPage" ], "additionalProperties": false, "description": "One page of rows." } ``` ### 400 A parameter is invalid. `message` says which. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "A parameter is invalid. `message` says which." } ``` ### 401 The API key is missing or wrong. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "The API key is missing or wrong." } ``` ### 402 The subscription is paused. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "The subscription is paused." } ``` ### 404 No table with this ID in your organization. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "No table with this ID in your organization." } ``` ### 429 Too many requests. See "Rate limits". Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "Too many requests. See \"Rate limits\"." } ``` ### 500 Something failed on our side. Safe to retry. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "Something failed on our side. Safe to retry." } ``` ## Example request ```bash curl -X GET "https://api-v2.baseloop.io/v1/tables//rows" \ -H "Authorization: Bearer " ``` # Search and filter rows (https://docs.baseloop.io/api-reference/rows/query-rows) `POST https://api-v2.baseloop.io/v1/tables/{tableId}/rows/query` Returns the same rows as GET /tables/{tableId}/rows, narrowed by text search, column filters or both. ## Authentication Send your API key as a bearer token: `Authorization: Bearer `. Your organization API key, from Settings > API key in the app. ## Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `tableId` | path | yes | string | Table ID from `GET /tables`. | ## Request body Content type: `application/json` Schema: ```json { "type": "object", "properties": { "limit": { "type": "integer", "exclusiveMinimum": 0, "maximum": 100, "default": 100, "description": "Rows per page, 1 to 100. Default 100." }, "cursor": { "type": "string", "maxLength": 500, "description": "`nextCursor` from the previous page. Only valid with the same search and filters." }, "q": { "type": "string", "maxLength": 100, "description": "Same as `query`. When both are sent, `query` wins." }, "query": { "type": "string", "maxLength": 100, "description": "Case-insensitive text search across the row's cells, up to 100 characters." }, "filters": { "type": "object", "properties": { "combinator": { "type": "string", "enum": [ "and", "or" ], "description": "\"and\" (default): every rule must match. \"or\": any rule." }, "rules": { "type": "array", "items": { "anyOf": [ { "type": "object", "properties": { "fieldId": { "type": "string", "description": "Column ID from the schema route." }, "operator": { "type": "string", "enum": [ "=", "!=", ">", ">=", "<", "<=", "contains", "doesNotContain", "startsWith", "containsAnyOf", "doesNotContainAnyOf", "in", "notIn", "null", "notNull", "isDatePreset", "between", "hasError", "hasNoError", "hasNotRun", "runConditionNotMet", "isFound", "isNotFound" ], "description": "Which operators a column accepts depends on its type. See \"Filtering rows\"." }, "value": { "anyOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "array", "items": { "type": "string" } }, { "type": "object", "properties": { "start": { "type": "string" }, "end": { "type": "string" } }, "required": [ "start", "end" ], "additionalProperties": false } ], "description": "What to compare with. Leave it out for null, notNull and the run-status operators. Values that are not text are sent as JSON text." } }, "required": [ "fieldId", "operator" ], "additionalProperties": false }, { "type": "object", "properties": { "combinator": { "type": "string", "enum": [ "and", "or" ], "description": "\"and\" (default): every rule must match. \"or\": any rule." }, "rules": { "type": "array", "items": { "anyOf": [ { "type": "object", "properties": { "fieldId": { "type": "string", "description": "Column ID from the schema route." }, "operator": { "type": "string", "enum": [ "=", "!=", ">", ">=", "<", "<=", "contains", "doesNotContain", "startsWith", "containsAnyOf", "doesNotContainAnyOf", "in", "notIn", "null", "notNull", "isDatePreset", "between", "hasError", "hasNoError", "hasNotRun", "runConditionNotMet", "isFound", "isNotFound" ], "description": "Which operators a column accepts depends on its type. See \"Filtering rows\"." }, "value": { "anyOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "array", "items": { "type": "string" } }, { "type": "object", "properties": { "start": { "type": "string" }, "end": { "type": "string" } }, "required": [ "start", "end" ], "additionalProperties": false } ], "description": "What to compare with. Leave it out for null, notNull and the run-status operators. Values that are not text are sent as JSON text." } }, "required": [ "fieldId", "operator" ], "additionalProperties": false }, { "type": "object", "properties": { "combinator": { "type": "string", "enum": [ "and", "or" ], "description": "\"and\" (default): every rule must match. \"or\": any rule." }, "rules": { "type": "array", "items": { "anyOf": [ { "type": "object", "properties": { "fieldId": { "type": "string", "description": "Column ID from the schema route." }, "operator": { "type": "string", "enum": [ "=", "!=", ">", ">=", "<", "<=", "contains", "doesNotContain", "startsWith", "containsAnyOf", "doesNotContainAnyOf", "in", "notIn", "null", "notNull", "isDatePreset", "between", "hasError", "hasNoError", "hasNotRun", "runConditionNotMet", "isFound", "isNotFound" ], "description": "Which operators a column accepts depends on its type. See \"Filtering rows\"." }, "value": { "anyOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "array", "items": { "type": "string" } }, { "type": "object", "properties": { "start": { "type": "string" }, "end": { "type": "string" } }, "required": [ "start", "end" ], "additionalProperties": false } ], "description": "What to compare with. Leave it out for null, notNull and the run-status operators. Values that are not text are sent as JSON text." } }, "required": [ "fieldId", "operator" ], "additionalProperties": false }, { "type": "object", "properties": { "combinator": { "type": "string", "enum": [ "and", "or" ], "description": "\"and\" (default): every rule must match. \"or\": any rule." }, "rules": { "type": "array", "items": { "anyOf": [ { "type": "object", "properties": { "fieldId": { "type": "string", "description": "Column ID from the schema route." }, "operator": { "type": "string", "enum": [ "=", "!=", ">", ">=", "<", "<=", "contains", "doesNotContain", "startsWith", "containsAnyOf", "doesNotContainAnyOf", "in", "notIn", "null", "notNull", "isDatePreset", "between", "hasError", "hasNoError", "hasNotRun", "runConditionNotMet", "isFound", "isNotFound" ], "description": "Which operators a column accepts depends on its type. See \"Filtering rows\"." }, "value": { "anyOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "array", "items": { "type": "string" } }, { "type": "object", "properties": { "start": { "type": "string" }, "end": { "type": "string" } }, "required": [ "start", "end" ], "additionalProperties": false } ], "description": "What to compare with. Leave it out for null, notNull and the run-status operators. Values that are not text are sent as JSON text." } }, "required": [ "fieldId", "operator" ], "additionalProperties": false }, { "type": "object", "properties": { "combinator": { "type": "string", "enum": [ "and", "or" ], "description": "\"and\" (default): every rule must match. \"or\": any rule." }, "rules": { "type": "array", "items": { "type": "object", "properties": { "fieldId": { "type": "string", "description": "Column ID from the schema route." }, "operator": { "type": "string", "enum": [ "=", "!=", ">", ">=", "<", "<=", "contains", "doesNotContain", "startsWith", "containsAnyOf", "doesNotContainAnyOf", "in", "notIn", "null", "notNull", "isDatePreset", "between", "hasError", "hasNoError", "hasNotRun", "runConditionNotMet", "isFound", "isNotFound" ], "description": "Which operators a column accepts depends on its type. See \"Filtering rows\"." }, "value": { "anyOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "array", "items": { "type": "string" } }, { "type": "object", "properties": { "start": { "type": "string" }, "end": { "type": "string" } }, "required": [ "start", "end" ], "additionalProperties": false } ], "description": "What to compare with. Leave it out for null, notNull and the run-status operators. Values that are not text are sent as JSON text." } }, "required": [ "fieldId", "operator" ], "additionalProperties": false }, "maxItems": 25 } }, "required": [ "rules" ], "additionalProperties": false } ] }, "maxItems": 25 } }, "required": [ "rules" ], "additionalProperties": false } ] }, "maxItems": 25 } }, "required": [ "rules" ], "additionalProperties": false } ] }, "maxItems": 25 } }, "required": [ "rules" ], "additionalProperties": false } ] }, "maxItems": 25, "description": "Rules, or groups of rules. Groups nest up to 5 levels counting this one, with up to 25 entries in each group and 100 across all groups together (a group counts as one entry)." } }, "additionalProperties": false, "description": "Column filters." } }, "additionalProperties": false, "examples": [ { "limit": 25, "query": "acme", "filters": { "combinator": "and", "rules": [ { "fieldId": "", "operator": "notNull" } ] } } ] } ``` ## Responses ### 200 One page of matching rows. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "rows": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "tableId": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" }, "createdByUserId": { "type": [ "string", "null" ], "description": "ID of the member who added the row, when known." }, "cells": { "type": "object", "additionalProperties": { "type": "object", "properties": { "value": { "description": "The cell value: text, number, boolean, object or array depending on the column. null when empty." }, "status": { "description": "How the value got there. manual: entered by a person or sent in. success: an action produced it. failed: the action errored (see errorMessage). skipped or stopped: the action did not run. queued, waiting or running: the action is not done yet. null when not set." }, "isTruncated": { "type": "boolean", "description": "Present and true when the value was cut to 200 characters." }, "valuePreview": { "type": "string", "description": "The first 200 characters, when the value was cut." }, "errorMessage": { "description": "Why the cell failed, when it did." } }, "additionalProperties": false }, "description": "Cells keyed by column ID. Empty cells are left out. Get column names from the schema route." } }, "required": [ "id", "tableId", "createdAt", "updatedAt", "createdByUserId", "cells" ], "additionalProperties": false } }, "limit": { "type": "integer" }, "nextCursor": { "type": [ "string", "null" ], "description": "Pass it as `cursor` to get the next page. null on the last page." }, "hasNextPage": { "type": "boolean" } }, "required": [ "rows", "limit", "nextCursor", "hasNextPage" ], "additionalProperties": false, "description": "One page of matching rows." } ``` ### 400 A parameter is invalid. `message` says which. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "A parameter is invalid. `message` says which." } ``` ### 401 The API key is missing or wrong. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "The API key is missing or wrong." } ``` ### 402 The subscription is paused. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "The subscription is paused." } ``` ### 404 No table with this ID in your organization. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "No table with this ID in your organization." } ``` ### 429 Too many requests. See "Rate limits". Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "Too many requests. See \"Rate limits\"." } ``` ### 500 Something failed on our side. Safe to retry. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Always \"API Error\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "Something failed on our side. Safe to retry." } ``` ## Example request ```bash curl -X POST "https://api-v2.baseloop.io/v1/tables//rows/query" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"limit":25,"query":"acme","filters":{"combinator":"and","rules":[{"fieldId":"","operator":"notNull"}]}}' ``` # Send rows to a table (https://docs.baseloop.io/api-reference/webhooks/send-webhook-rows) `POST https://api-v2.baseloop.io/v1/webhook/{id}` Adds rows to a table that has a webhook. Send one JSON object, an array of objects, or an object with the array under "data". Each object becomes one row: the webhook column keeps the whole object and the columns mapped from it in the app fill in. Up to 500 objects and 1 MB per request. Rows can take up to 10 seconds to appear. No API key: anyone with the URL can add rows, so keep it private. ## Authentication No API key. The URL identifies the target. ## Parameters | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `id` | path | yes | string | The last part of the webhook URL shown on the table in the app. | ## Request body Content type: `application/json` Schema: ```json { "anyOf": [ { "type": "object", "additionalProperties": {} }, { "type": "array", "items": {} } ], "examples": [ { "email": "jane@acme.com", "firstName": "Jane", "company": "Acme" } ] } ``` ## Responses ### 200 The rows are queued and appear within 10 seconds. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ true ] }, "message": { "type": "string", "description": "Like \"Processing 3 records\"." } }, "required": [ "success", "message" ], "additionalProperties": false, "description": "The rows are queued and appear within 10 seconds." } ``` ### 400 The body is empty, has no objects, or has more than 500. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Short name of the error, like \"Bad Request\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "The body is empty, has no objects, or has more than 500." } ``` ### 404 No webhook with this ID. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Short name of the error, like \"Bad Request\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "No webhook with this ID." } ``` ### 413 The body is larger than 1 MB. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Short name of the error, like \"Bad Request\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "The body is larger than 1 MB." } ``` ### 429 More than 100 requests in one second. Content type: `application/json` Schema: ```json { "type": "object", "properties": { "statusCode": { "type": "integer" }, "error": { "type": "string", "description": "Short name of the error, like \"Bad Request\"." }, "message": { "type": "string", "description": "What went wrong, in plain words." } }, "required": [ "statusCode", "error", "message" ], "additionalProperties": false, "description": "More than 100 requests in one second." } ``` ## Example request ```bash curl -X POST "https://api-v2.baseloop.io/v1/webhook/" \ -H "Content-Type: application/json" \ -d '{"email":"jane@acme.com","firstName":"Jane","company":"Acme"}' ```