> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://apidocs.polytomic.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://apidocs.polytomic.com/_mcp/server.

# REST API 2025-09-18 migration guide

This guide describes everything that has changed between `2024-02-08` and
`2025-09-18`: the new features available, the removed and relocated endpoints,
and the request and response shape changes that callers need to adopt.

The sections are organized by area. Most clients will only need to update a
handful of routes; the [quick checklist](#quick-checklist) at the end summarises
the breaking changes. Each section links into the detailed API reference for
the affected endpoints.

## What's new

`2025-09-18` adds several capabilities that did not exist in `2024-02-08`.

### Connection Proxy API

You can now make ad-hoc HTTP requests to a connection's upstream API using the
credentials Polytomic already stores.

* [`POST /api/connections/{id}/proxy`](/api-reference/connections/execute-proxy)
  — proxy an HTTP request through a connection. Polytomic attaches the
  connection's base URL, auth headers, and inherited query parameters; the
  caller supplies `method`, `path`, optional `query`, `headers`, and `body`.
* [`GET /api/connections/{id}/proxy/info`](/api-reference/connections/get-proxy-info)
  — returns the proxy contract for a connection: the inherited base URL,
  locked query parameters, locked headers (with sensitive values redacted),
  allowed HTTP methods, body and header rules, size and rate limits, and
  24-hour usage statistics.

The proxy enforces per-connection and per-organization rate limits, a 30 second
upstream timeout, a 256 KiB request body cap, and a 1 MiB response body cap
(responses above that are returned with `truncated: true`). Each call returns a
`proxyCallId` you can correlate with audit logs.

The feature is enabled by request; contact Polytomic support to enable it.

### Per-execution console logs

The console log stream that powers the in-product execution view is now
available over the REST API. Each endpoint returns the most recent entries and
supports cursor pagination via `limit` and `after`.

* [`GET /api/syncs/{sync_id}/executions/{id}/consolelog`](/api-reference/model-sync/executions/get-console-logs)
  — model sync execution.
* [`GET /api/bulk/syncs/{sync_id}/executions/{execution_id}/consolelog`](/api-reference/bulk-sync/executions/get-console-logs)
  — bulk sync execution, aggregated across schemas.
* [`GET /api/bulk/syncs/{sync_id}/executions/{execution_id}/schemas/{schema_id}/consolelog`](/api-reference/bulk-sync/executions/get-schema-console-logs)
  — bulk sync execution scoped to a single schema.

These complement the existing log export endpoints; use console logs while an
execution is in flight and the structured logs after it completes.

### Patch schema fields

[`PATCH /api/connections/{connection_id}/schemas/{schema_id}/fields/{field_id}`](/api-reference/schemas/patch-field)
applies a partial update to a single field. Only the fields you include in the
body are changed, so you can rename a label or change a JSONPath without
re-sending the rest of the field definition. The existing POST and DELETE
endpoints are unchanged.

### Per-schedule resync mode for bulk syncs

Each `additional_schedules` entry on a bulk sync now accepts a `resync_mode`
(one of `normal`, `refetch`, `resync`, `rebuild`) that controls how the
destination is treated when that schedule fires. The previous API supported a
single sync-wide schedule and had no way to express "run a daily incremental
plus a weekly full rebuild." See
[Bulk Sync: list, create, and update](#bulk-sync-list-create-and-update) below
for the new payload shape.

### Entity lookup

A new endpoint lets you resolve any Polytomic UUID without knowing what kind
of resource it belongs to:

* [`GET /api/entities/{id}`](/api-reference/entities/get) (user or
  organization-scoped key) — resolve an ID within the caller's organization.
* [`GET /api/organizations/entities/{id}`](/api-reference/entities/get-for-partner)
  (partner key) — resolve an ID across organizations the partner can access.

The response includes the entity `type` (`organization`, `user`, `connection`,
`model`, `sync`, `sync_execution`, `bulk_sync`, or `bulk_sync_execution`), a
`canonical_path` you can immediately `GET`, and `relationships` for nested
resources (e.g. a sync execution returns its parent sync). This is useful
when following IDs that appear in logs, webhooks, or audit records.

### Model sync execution logs index

[`GET /api/syncs/{sync_id}/executions/{id}/logs`](/api-reference/model-sync/executions/get-logs-index)
returns a compact index of the record-log types produced by a model sync
execution. The response contains a record count and a per-type retrieval
endpoint for each kind of log file that was actually produced (`records`,
`inserts`, `updates`, `deletes`, `errors`, `warnings`); types with no records
are omitted.

This endpoint is the canonical way to discover the signed URLs for execution
log segments. It pairs with the
[`sync.completed` webhook payload change](#sync-completed-webhook-payload-trimmed)
below.

## Authentication and route layout

### Organization and user endpoints split by credential type

`2024-02-08` used a single route family for both the caller's own organization
and partner cross-organization access, and let the server infer intent from
the credential. `2025-09-18` splits these into two distinct route families so
that intent is explicit in the URL.

| Operation                                 | 2024-02-08                                         | 2025-09-18                                                                                                                                                                                            |
| ----------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Get current organization                  | *(not exposed)*                                    | [`GET /api/organization`](/api-reference/organization/get-current)                                                                                                                                    |
| Create user in current organization       | `POST /api/organizations/{org_id}/users`           | [`POST /api/organization/users`](/api-reference/users/create-current-org-user)                                                                                                                        |
| List users in current organization        | `GET /api/organizations/{org_id}/users`            | [`GET /api/organization/users`](/api-reference/users/list-current-org-users)                                                                                                                          |
| Get user in current organization          | `GET /api/organizations/{org_id}/users/{id}`       | [`GET /api/organization/users/{id}`](/api-reference/users/get-current-org-user)                                                                                                                       |
| Update user in current organization       | `PUT /api/organizations/{org_id}/users/{id}`       | [`PUT /api/organization/users/{id}`](/api-reference/users/update-current-org-user)                                                                                                                    |
| Delete user in current organization       | `DELETE /api/organizations/{org_id}/users/{id}`    | [`DELETE /api/organization/users/{id}`](/api-reference/users/delete-current-org-user)                                                                                                                 |
| List organizations (partner)              | `GET /api/organizations`                           | [`GET /api/organizations`](/api-reference/organization/list)                                                                                                                                          |
| Get / update / delete organization        | `... /api/organizations/{id}`                      | [`GET`](/api-reference/organization/get) / [`PUT`](/api-reference/organization/update) / [`DELETE`](/api-reference/organization/delete) `/api/organizations/{id}`                                     |
| CRUD users across organizations (partner) | `... /api/organizations/{org_id}/users[/{id}]`     | [`Create`](/api-reference/users/create) / [`List`](/api-reference/users/list) / [`Get`](/api-reference/users/get) / [`Update`](/api-reference/users/update) / [`Delete`](/api-reference/users/delete) |
| Create API key for a user (partner)       | `POST /api/organizations/{org_id}/users/{id}/keys` | [`POST /api/organizations/{org_id}/users/{id}/keys`](/api-reference/users/create-api-key)                                                                                                             |

**Migration rule.** Decide based on the credential you are using:

* A user session or an organization-scoped API key acting **within its own
  organization** must use `/api/organization/...` (singular).
* A partner key acting **across organizations** must use
  `/api/organizations/...` (plural). The plural routes now reject
  organization-scoped credentials.

If your `2024-02-08` client used the plural routes with a non-partner
credential, point it at the new singular routes; the request and response
bodies are otherwise unchanged.

### Connection share endpoint moved

The connection share endpoints have been harmonized with the rest of the
connections surface:

| Operation                         | 2024-02-08                                           | 2025-09-18                                                                                                                             |
| --------------------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Share a connection (partner)      | `POST /api/connections/{parent_connection_id}/share` | [`POST /api/organizations/{org_id}/connections/{connection_id}/shared`](/api-reference/connections/create-shared-connection)           |
| List shared copies (partner)      | `GET /api/connections/{parent_connection_id}/shared` | [`GET /api/organizations/{org_id}/connections/{connection_id}/shared`](/api-reference/connections/list-shared-connections-for-partner) |
| List shared copies (caller's org) | `GET /api/connections/{parent_connection_id}/shared` | [`GET /api/connections/{id}/shared`](/api-reference/connections/list-shared-connections)                                               |

The trailing path segment is now `shared` (a noun describing the resource
collection) rather than `share` (a verb), matching the rest of the API.

## Bulk Sync: list, create, and update

The bulk sync [create](/api-reference/bulk-sync/create),
[update](/api-reference/bulk-sync/update), [list](/api-reference/bulk-sync/list),
and [get](/api-reference/bulk-sync/get) endpoints have been overhauled:

* The single `schedule` parameter has been removed.
* A required `default_schedule` parameter and an optional
  `additional_schedules` array have been added.
* Each additional schedule can target specific schemas via `selective_mode`
  and `schemas`, and can override the per-execution resync behavior via
  `resync_mode`.

Every bulk sync now operates in multi-schedule mode by default; the legacy
`multi` schedule type is no longer accepted.

### Schedule payload migration

**Old `2024-02-08` update payload, using `schedule`:**

```json
{
  "name": "my bulk sync",
  "schedule": {
    "frequency": "multi",
    "multi": {
      "schedules": [
        {
          "item": "incrementalFields",
          "schedule": {
            "frequency": "continuous"
          }
        },
        {
          "item": "nonincrementalFields",
          "schedule": {
            "frequency": "daily",
            "hour": "05",
            "minute": "00"
          }
        }
      ]
    }
  }
}
```

**New `2025-09-18` update payload, using `default_schedule` and
`additional_schedules`:**

```json
{
  "name": "my bulk sync",
  "default_schedule": {
    "frequency": "continuous"
  },
  "additional_schedules": [
    {
      "selective_mode": "nonincrementalFields",
      "frequency": "daily",
      "hour": "05",
      "minute": "00"
    }
  ]
}
```

The `default_schedule` always applies to every schema and field; it cannot
carry `selective_mode`, `schemas`, or `resync_mode`. `additional_schedules`
entries may scope themselves to specific schemas (`schemas: ["public.users"]`)
and may set `resync_mode` (`normal`, `refetch`, `resync`, `rebuild`) to
override the default destination behavior when that schedule fires.

The response shape of [`GET /api/bulk/syncs`](/api-reference/bulk-sync/list),
[`GET /api/bulk/syncs/{id}`](/api-reference/bulk-sync/get),
[`POST /api/bulk/syncs`](/api-reference/bulk-sync/create), and
[`PUT /api/bulk/syncs/{id}`](/api-reference/bulk-sync/update) mirrors this:
each returns a `default_schedule` object and an `additional_schedules` array,
both with `created_at` / `updated_at` / `created_by` / `updated_by` metadata.

## Model Sync: list syncs

[`GET /api/syncs`](/api-reference/model-sync/list) now returns paginated,
lighter-weight results so it can be used for discovery without paying the cost
of loading every sync's full configuration:

* Results are paginated. The response includes a `pagination.next_page_token`
  cursor; pass it back as the `page_token` query parameter to retrieve the
  next page. The page size is capped at 50.
* Results are filterable via `active`, `mode`, and `target_connection_id`
  query parameters.
* The list response shape does not include every sync property. Notably:
  * The target connection is not expanded — only `target_connection_id` and
    target ID fields are returned.
  * Field mappings, overrides, and filters are omitted.

If you need the full configuration of a sync, follow up with the existing
[`GET /api/syncs/{id}`](/api-reference/model-sync/get) endpoint. Use list to
discover or filter syncs in an account; use get to retrieve the full
configuration of a single one.

## Model Sync executions: explicit cancel

The status-update endpoint that was used to cancel a model sync execution has
been replaced by an explicit cancel endpoint, mirroring the bulk sync API:

| Operation                     | 2024-02-08                                                    | 2025-09-18                                                                                        |
| ----------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| Cancel a model sync execution | `PUT /api/syncs/{sync_id}/executions/{id}` with a status body | [`POST /api/syncs/{sync_id}/executions/{id}/cancel`](/api-reference/model-sync/executions/cancel) |

The new endpoint takes no body and returns a confirmation envelope. Attempting
to cancel a terminal (completed or failed) execution returns `400`.

There is no longer a generic "update execution" endpoint; executions are
write-once apart from cancellation.

## Removed endpoints

| 2024-02-08 endpoint                                  | Replacement                                                                                                                                                                              |
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PUT /api/syncs/{sync_id}/executions/{id}`           | [`POST /api/syncs/{sync_id}/executions/{id}/cancel`](/api-reference/model-sync/executions/cancel)                                                                                        |
| `GET /api/connections/{id}/modelsync/target`         | [`GET /api/connections/{id}/modelsync/target/fields`](/api-reference/model-sync/targets/get-fields) (the target-shape endpoint was redundant with fields)                                |
| `POST /api/connections/{parent_connection_id}/share` | [`POST /api/organizations/{org_id}/connections/{connection_id}/shared`](/api-reference/connections/create-shared-connection)                                                             |
| `GET /api/connections/{parent_connection_id}/shared` | [`GET /api/connections/{id}/shared`](/api-reference/connections/list-shared-connections) or [the partner-scoped variant](/api-reference/connections/list-shared-connections-for-partner) |

## Quick checklist

When upgrading a client from `2024-02-08` to `2025-09-18`:

* [ ] Update bulk sync [create](/api-reference/bulk-sync/create) and
  [update](/api-reference/bulk-sync/update) payloads to use
  `default_schedule` and `additional_schedules`; remove any use of the
  `multi` schedule type.
* [ ] Parse the new `default_schedule` / `additional_schedules` fields in
  bulk sync [list](/api-reference/bulk-sync/list) and
  [get](/api-reference/bulk-sync/get) responses.
* [ ] Page through [`GET /api/syncs`](/api-reference/model-sync/list) using
  the `next_page_token` cursor, and switch to
  [`GET /api/syncs/{id}`](/api-reference/model-sync/get) for full sync
  configuration.
* [ ] Route organization and user operations based on credential type
  (singular `/api/organization/...` for self, plural
  `/api/organizations/...` for partner).
* [ ] Replace `POST .../share` with
  [`POST .../shared`](/api-reference/connections/create-shared-connection)
  for connection sharing, and update the parent path to the new
  partner-scoped form.
* [ ] Replace `PUT /api/syncs/{sync_id}/executions/{id}` cancellations with
  [`POST .../cancel`](/api-reference/model-sync/executions/cancel).
* [ ] If you used `GET /api/connections/{id}/modelsync/target`, switch to the
  [`target/fields`](/api-reference/model-sync/targets/get-fields) variant.

You may also want to adopt the new capabilities described under
[What's new](#whats-new): the
[connection proxy](/api-reference/connections/execute-proxy),
[entity lookup](/api-reference/entities/get), console log streaming for
[model](/api-reference/model-sync/executions/get-console-logs) and
[bulk](/api-reference/bulk-sync/executions/get-console-logs) sync executions,
[schema-field patching](/api-reference/schemas/patch-field), and per-schedule
resync modes on bulk syncs.