> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gigstack.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage Airtable payment imports

> Integration guide for Manage Airtable payment imports

First complete the [reviewed provider setup](/guides/provider-setup). Then choose a base
and table, map Airtable fields to payment fields, and register the import webhook.
Use a verified personal MCP credential or signed-in Firebase person with current
team permissions. Team API keys cannot act as their creator.

Airtable has one shared production connection. `expected_livemode:false` selects
no separate Airtable sandbox: it asserts that the authenticated gigstack mode shown
in your confirmation is test mode. Provider webhook creation/deletion still affects
the real connected Airtable account. Confirm those effects before sending.

## Choose a base and table

```bash theme={null}
export GIGSTACK_API_BASE="https://api.gigstack.io/v2"
export TEAM_ID="team_example"
curl --fail-with-body "$GIGSTACK_API_BASE/teams/$TEAM_ID/integrations/airtable/bases" \
  -H "Authorization: Bearer $GIGSTACK_API_KEY"
```

Read `data.data`. If `data.has_more` is true, repeat with the opaque
`data.next_cursor` as the `cursor` query parameter. Then call
`GET /teams/{id}/integrations/airtable/bases/{baseId}/tables` to list each table's
fields. Table results are not paginated. Save provider IDs from these responses.

## Register an import mapping

Create and save a UUIDv4 before submitting. Replace the example IDs with the
selected base/table/field IDs. This example imports Airtable amounts as gigstack
payments; inspect your table and mapping before confirmation.

```bash theme={null}
OPERATION_ID="11111111-1111-4111-8111-111111111111"
curl --fail-with-body "$GIGSTACK_API_BASE/teams/$TEAM_ID/integrations/airtable/webhooks" \
  -H "Authorization: Bearer $GIGSTACK_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"operation_id":"11111111-1111-4111-8111-111111111111","expected_livemode":false,"base_id":"app_example","table_id":"tbl_example","field_map":{"amount":"fld_amount"},"mapping_config":{"currencyDefault":"MXN"},"confirmed":true}'
```

`field_map` maps payment paths to existing Airtable field names or IDs. `amount` is
required. Supported paths include `currency`, `status`, `payment_form`, `exchange`,
`items`, documented `client` identity/address fields and safe `metadata.*` paths.
Arbitrary payment fields and prototype-like paths are rejected. Currency and
payment-form defaults follow the exact request schema.

A successful HTTP response is `{success:true,data:...,timestamp:...}`. For mutations,
inspect `data.status`: `completed` confirms that operation, while `processing` and
`outcome_unknown` do not. A first confirmed registration may include `data.webhook`;
replay/readback may omit it. List the local mappings to read current state.

## Inspect mappings and results

* `GET /teams/{id}/integrations/airtable/webhooks` lists the selected mode's mappings.
  Use `limit`, `cursor`, `base_id` and `status` for scoped paging/filtering.
* `GET /teams/{id}/integrations/airtable/webhooks?scope=shared` explicitly inspects
  both modes and legacy records. It requires configuration authority.
* `GET /teams/{id}/integrations/airtable/bases/{baseId}/webhooks/remote` reads the
  shared provider inventory. It returns no notification URLs, MACs or tokens.
* `GET /teams/{id}/integrations/airtable/operations/{operationId}` reads the saved
  operation. Its `targets` has separate `has_more` and `next_cursor` pagination.

Mapping lists expose `can_manage`, `can_recover_registration` and an appropriately
scoped `blocking_operation_id`. These help present available actions; the backend
rechecks current authority when you act. Disconnected teams can still list their
local mappings without OAuth credentials.

## Remove mappings or disconnect

`DELETE /teams/{id}/integrations/airtable/webhooks/{webhookId}` takes a new saved
`operation_id`, `expected_livemode` and `confirmed:true` in its JSON body.

`POST /teams/{id}/integrations/airtable/disconnect` also requires
`acknowledge_shared_connection:true`. It disables imports and removes stored hooks
across both modes, including legacy records. It retains encrypted OAuth credentials
and does not revoke the person's Airtable grant.

Cleanup is bounded. If `continuation_required:true`, an explicit continuation uses
the **same UUID and identical payload** to process previously unattempted targets.
It does not resend a target whose outcome is unknown. Never change the payload under
the same UUID; that returns `409 idempotency_conflict`. Local disablement is not
proof of remote deletion; inspect the target statuses and counts.

## Recover an uncertain result

Keep the operation ID after any timeout. Read it, then call
`POST /teams/{id}/integrations/airtable/operations/{operationId}/reconcile` with `{}`.
Reconcile reads evidence and never repeats an uncertain create/delete. A new UUID
is a new action, not an idempotent retry. Registration cannot recover a lost one-time
MAC by recreating the same webhook.

If an uncertain OAuth refresh blocks cleanup, a current administrator can prepare a
reviewed browser recovery session with:

```json theme={null}
{
  "provider": "airtable",
  "expected_livemode": false,
  "recovery_operation_id": "11111111-1111-4111-8111-111111111111",
  "acknowledge_unconfirmed_effects": true
}
```

Send this to `POST /teams/{id}/integration-connection-sessions`. Preparation disables
local imports in bounded pages. Inspect `data.recovery.snapshot_complete`; each
continuation needs explicit acknowledgment. GET never advances preparation. The
person then completes the returned authenticated browser handoff.

Recovery stores restricted credentials with imports disabled. It preserves the old
unknown outcome and does not release its lock. Only a verified matching Airtable
identity can establish old target evidence. A different or previously unverified
identity cannot prove cleanup by seeing no webhooks; legacy unverified identity
requires operator-assisted verification.

The browser guides the person through a separately confirmed cleanup with a **new**
operation UUID referencing `recovery_operation_id`, shared-connection acknowledgment
and acknowledgment of unconfirmed effects. For a registration orphan, cleanup uses
DELETE on its proven webhook ID; unregister/disconnect recovery uses POST disconnect.
The old receipt points to `cleanup_operation_id` and stays unknown. Reconnect through
ordinary reviewed setup only after that separate cleanup completes. Reconnection is
never automatic.

## Errors and validation

`401` requires a verified personal credential. `403` indicates current authority or
account state refused the operation. `409 mode_changed` requires reviewing the newly
selected mode; lock/recovery conflicts require inspecting the existing operation.
After `504` or an interrupted request, preserve the UUID and read its receipt.

These workflows have offline tests with mocked provider effects. Public deployment,
provider authorization and end-to-end live verification are separate release steps.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.