Oneprofile Table Events API
Server-sent change feed for a table's grid.
Server-sent change feed for a table's grid.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/getoneprofile-ai:getoneprofile-ai-table-events-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
contact:
email: support@getoneprofile.ai
name: Oneprofile Support
description: REST API reference for Oneprofile, the GTM data layer for your CRM. Manage tables, enrichments, and integrations. Authenticate with an API key to get started.
termsOfService: https://www.getoneprofile.ai/terms
title: Reference | Oneprofile Table Events API
version: 1.0.42765316646
tags:
- description: Server-sent change feed for a table's grid.
name: table-events
paths:
/tables/{table_id}/events/:
get:
description: 'Server-sent event stream of a table''s changes: row cell deltas, run progress, and column / display-preference / row-set invalidation signals. Replaces the 2-second status poll, so an idle table costs nothing.
Deltas carry the row''s `version`, the same watermark the rows list carries, so applying one twice or out of order is a no-op. There is deliberately NO replay log: clients refetch once on every connect, and a mid-stream gap is reported as a `resync` frame meaning the same thing.
The server closes the stream after a few minutes with a `reconnect` frame; reconnect with a fresh token. Comment heartbeats keep intermediaries from dropping an idle connection.
Requires Clerk authentication; API keys are rejected. There is deliberately no 404: an unknown or foreign table streams heartbeats only, because the channel is org-scoped and leaks nothing.'
operationId: stream_table_events
parameters:
- in: path
name: table_id
required: true
schema:
format: uuid
title: Table Id
type: string
responses:
'200':
content:
text/event-stream:
schema:
$ref: '#/components/schemas/TableChangeEventSchema'
type: string
description: A stream of change events; each SSE frame's `data` is one event object.
'401':
content:
text/event-stream:
schema:
$ref: '#/components/schemas/UnauthorizedResponse'
description: Unauthorized
'403':
content:
text/event-stream:
schema:
$ref: '#/components/schemas/ForbiddenResponse'
description: Forbidden
'422':
content:
text/event-stream:
schema:
$ref: '#/components/schemas/UnprocessableEntityResponse'
description: Invalid request made to the API.
'500':
content:
text/event-stream:
schema:
$ref: '#/components/schemas/ServerErrorResponse'
description: Internal server error.
'502':
content:
text/event-stream:
schema:
$ref: '#/components/schemas/ServerErrorResponse'
description: Bad gateway error.
'503':
content:
text/event-stream:
schema:
$ref: '#/components/schemas/ServerErrorResponse'
description: Service unavailable.
security:
- HTTPBearer: []
summary: Stream a table's change events
tags:
- table-events
components:
schemas:
TableReconnectEventSchema:
description: 'Final frame: the stream reached its maximum age. Reconnect for a fresh one.'
properties:
kind:
const: reconnect
default: reconnect
title: Kind
type: string
table_id:
format: uuid
title: Table Id
type: string
required:
- table_id
title: TableReconnectEventSchema
type: object
UnprocessableEntityIssue:
properties:
input:
anyOf:
- type: string
- type: integer
- type: number
- type: boolean
- items: {}
type: array
- additionalProperties: true
type: object
description: The user's input that caused the error.
title: Input
loc:
description: The location of the error. Always contains 1 or 2 elements. The first element is the type of location (e.g. 'body', 'query', 'path', 'header'). The second element is the name of the field that caused the error. If the error is not related to a specific field, the second element is not present.
items:
type: string
title: Loc
type: array
msg:
description: The message of the error. The error message to show to the user.
title: Msg
type: string
type:
description: The type of the error. Useful for frontend code to handle different types of errors.
title: Type
type: string
required:
- loc
- msg
- type
- input
title: UnprocessableEntityIssue
type: object
TableChangedEventSchema:
description: The table definition changed (name, description, or row counter).
properties:
description:
anyOf:
- type: string
- type: 'null'
title: Description
kind:
const: table_changed
default: table_changed
title: Kind
type: string
name:
title: Name
type: string
row_count:
title: Row Count
type: integer
table_id:
format: uuid
title: Table Id
type: string
updated_at:
format: date-time
title: Updated At
type: string
required:
- table_id
- name
- description
- row_count
- updated_at
title: TableChangedEventSchema
type: object
TableResyncEventSchema:
description: 'Events were lost; refetch everything.
Emitted when this client could not keep up with its queue, or when the
server''s Valkey link dropped and reconnected. There is no replay log by
design: a refetch is cheaper than maintaining one.'
properties:
kind:
const: resync
default: resync
title: Kind
type: string
reason:
title: Reason
type: string
table_id:
format: uuid
title: Table Id
type: string
required:
- table_id
- reason
title: TableResyncEventSchema
type: object
TableDeletedEventSchema:
description: The table was deleted; the next read will 404.
properties:
kind:
const: table_deleted
default: table_deleted
title: Kind
type: string
table_id:
format: uuid
title: Table Id
type: string
required:
- table_id
title: TableDeletedEventSchema
type: object
UnprocessableEntityResponse:
properties:
detail:
description: The detail of the error. This is the error message to show to the user. You should also use the issues field to show more detailed error messages per field. Use this field for a single liner error message.
title: Detail
type: string
issues:
description: The issues that caused the error. There can be multiple issues. Each issue is a user-facing error message.
items:
$ref: '#/components/schemas/UnprocessableEntityIssue'
title: Issues
type: array
required:
- detail
- issues
title: UnprocessableEntityResponse
type: object
TableRunChangedEventSchema:
description: A recompute run was created, progressed, or reached a terminal status.
properties:
kind:
const: run_changed
default: run_changed
title: Kind
type: string
run:
$ref: '#/components/schemas/TableRunDeltaSchema'
table_id:
format: uuid
title: Table Id
type: string
required:
- table_id
- run
title: TableRunChangedEventSchema
type: object
TableChangeEventSchema:
description: 'One frame of the change feed, discriminated by ``kind``.
A wrapper model rather than a bare union so the whole vocabulary lands in
the OpenAPI document as a single named schema the client can switch on.'
properties:
event:
description: The event body; switch on `kind`.
discriminator:
mapping:
cell_activity: '#/components/schemas/TableCellActivityEventSchema'
columns_changed: '#/components/schemas/TableColumnsChangedEventSchema'
hello: '#/components/schemas/TableHelloEventSchema'
reconnect: '#/components/schemas/TableReconnectEventSchema'
resync: '#/components/schemas/TableResyncEventSchema'
rows_changed: '#/components/schemas/TableRowsChangedEventSchema'
rows_invalidated: '#/components/schemas/TableRowsInvalidatedEventSchema'
run_changed: '#/components/schemas/TableRunChangedEventSchema'
table_changed: '#/components/schemas/TableChangedEventSchema'
table_deleted: '#/components/schemas/TableDeletedEventSchema'
ui_prefs_changed: '#/components/schemas/TableUIPrefsChangedEventSchema'
propertyName: kind
oneOf:
- $ref: '#/components/schemas/TableHelloEventSchema'
- $ref: '#/components/schemas/TableRowsChangedEventSchema'
- $ref: '#/components/schemas/TableRowsInvalidatedEventSchema'
- $ref: '#/components/schemas/TableColumnsChangedEventSchema'
- $ref: '#/components/schemas/TableUIPrefsChangedEventSchema'
- $ref: '#/components/schemas/TableChangedEventSchema'
- $ref: '#/components/schemas/TableDeletedEventSchema'
- $ref: '#/components/schemas/TableRunChangedEventSchema'
- $ref: '#/components/schemas/TableCellActivityEventSchema'
- $ref: '#/components/schemas/TableResyncEventSchema'
- $ref: '#/components/schemas/TableReconnectEventSchema'
title: Event
required:
- event
title: TableChangeEventSchema
type: object
TableRunDeltaSchema:
description: One run's current state; mirrors the REST run schema so clients can drop it straight in.
properties:
cells_awaiting:
default: 0
description: Cells held because an input they read has not been computed yet; not terminal, counted within cells_done.
title: Cells Awaiting
type: integer
cells_done:
title: Cells Done
type: integer
cells_failed:
title: Cells Failed
type: integer
cells_no_data:
default: 0
description: 'No-data cells: ran clean but found nothing.'
title: Cells No Data
type: integer
cells_skipped:
default: 0
description: 'Deliberately skipped cells: missing input or false condition.'
title: Cells Skipped
type: integer
cells_total:
title: Cells Total
type: integer
column_id:
anyOf:
- format: uuid
type: string
- type: 'null'
title: Column Id
column_ids:
anyOf:
- items:
format: uuid
type: string
type: array
- type: 'null'
description: Every column the run's plan covers, in layer order. Optional so a frame enqueued by an older worker still deserializes; absent means fall back to column_id.
title: Column Ids
completed_at:
anyOf:
- format: date-time
type: string
- type: 'null'
title: Completed At
created_at:
format: date-time
title: Created At
type: string
credits_charged:
default: 0
description: Credits charged so far. Grows while the run works, as its finished cells are settled every few seconds; final once the run ends.
title: Credits Charged
type: number
error:
anyOf:
- type: string
- type: 'null'
title: Error
id:
format: uuid
title: Id
type: string
row_scope:
anyOf:
- $ref: '#/components/schemas/TableRunRowScopeSchema'
- type: 'null'
description: The rows this run resolved to. Optional so a frame enqueued by an older worker still deserializes mid-rolling-deploy; absent reads as all_rows.
started_at:
anyOf:
- format: date-time
type: string
- type: 'null'
title: Started At
status:
title: Status
type: string
table_id:
format: uuid
title: Table Id
type: string
trigger:
title: Trigger
type: string
required:
- id
- table_id
- trigger
- status
- cells_total
- cells_done
- cells_failed
- error
- created_at
- started_at
- completed_at
title: TableRunDeltaSchema
type: object
ServerErrorResponse:
properties:
detail:
description: The detail of why the server returned an error.
title: Detail
type: string
required:
- detail
title: ServerErrorResponse
type: object
TableRowsChangedEventSchema:
description: One or more rows changed; apply the deltas directly, no refetch needed.
properties:
kind:
const: rows_changed
default: rows_changed
title: Kind
type: string
rows:
items:
$ref: '#/components/schemas/TableRowDeltaSchema'
title: Rows
type: array
table_id:
format: uuid
title: Table Id
type: string
required:
- table_id
- rows
title: TableRowsChangedEventSchema
type: object
TableCellActivityEventSchema:
description: 'One live agent step for one cell of an active run.
Published IMMEDIATELY, bypassing the post-commit queue, because steps are
telemetry about work that already happened, not table state, and a
compute page''s transaction spans the whole page. Never coalesced:
liveness is the point. The transport is lossy by design, so clients treat
the post-commit ``rows_changed`` settle as authoritative and use these
frames for display only.'
properties:
attempt:
default: 1
description: 1-based retry attempt; an increment means the investigation restarted, so clear the displayed trail.
title: Attempt
type: integer
column_id:
format: uuid
title: Column Id
type: string
kind:
const: cell_activity
default: cell_activity
title: Kind
type: string
record_id:
format: uuid
title: Record Id
type: string
run_id:
anyOf:
- format: uuid
type: string
- type: 'null'
title: Run Id
seq:
description: 0-based and strictly rising across the whole cell execution, retries included. The ordering key.
title: Seq
type: integer
step:
$ref: '#/components/schemas/TableCellActivityStepSchema'
table_id:
format: uuid
title: Table Id
type: string
required:
- table_id
- record_id
- column_id
- seq
- step
title: TableCellActivityEventSchema
type: object
ForbiddenResponse:
properties:
detail:
description: The detail of why the request is forbidden.
title: Detail
type: string
required:
- detail
title: ForbiddenResponse
type: object
TableUIPrefsChangedEventSchema:
description: 'Display preferences changed. Refetch the column list ALONE.
Separate from ``columns_changed`` for the same reason the status watermarks
are separate: a hide, pin, resize, or recolour must never refetch the rows
page and stats that a definition change refetches.'
properties:
kind:
const: ui_prefs_changed
default: ui_prefs_changed
title: Kind
type: string
table_id:
format: uuid
title: Table Id
type: string
required:
- table_id
title: TableUIPrefsChangedEventSchema
type: object
TableColumnsChangedEventSchema:
description: A column was created, edited, deleted, or reordered. Refetch columns and rows.
properties:
kind:
const: columns_changed
default: columns_changed
title: Kind
type: string
table_id:
format: uuid
title: Table Id
type: string
required:
- table_id
title: TableColumnsChangedEventSchema
type: object
UnauthorizedResponse:
properties:
detail:
description: The detail of why the request is unauthorized.
title: Detail
type: string
required:
- detail
title: UnauthorizedResponse
type: object
TableCellDeltaSchema:
description: 'One cell''s post-write state.
Deliberately carries NO ``computing`` flag. That flag is derived
(``stale`` AND the table has an active run) and a write has no idea whether
a run is active, so carrying it here would flicker cells out of their
computing state mid-run. Clients derive it from their own active-run state,
exactly as the REST responses do.'
properties:
computed_at:
anyOf:
- format: date-time
type: string
- type: 'null'
description: Last compute time, for formula cells.
title: Computed At
confidence:
anyOf:
- type: string
- type: 'null'
description: The agent's own read on its answer, when the action reports one.
title: Confidence
credits_charged:
anyOf:
- type: integer
- type: 'null'
description: Credits the last successful enrichment charged for this cell.
title: Credits Charged
error:
anyOf:
- type: string
- type: 'null'
description: Evaluation error, when the cell is in an error state.
title: Error
error_class:
anyOf:
- type: string
- type: 'null'
description: The failure's taxonomy class, when the cell is errored.
title: Error Class
manual_override:
default: false
description: A hand-entered correction runs will not overwrite.
title: Manual Override
type: boolean
settled_as:
default: pending
description: 'How the last attempt on this cell ENDED, never what it shows. The grid needs it to tell `no_data` (ran, found nothing) from `pending` (never ran): both render blank and neither carries an error.'
enum:
- succeeded
- no_data
- skipped
- failed
- pending
title: Settled As
type: string
skipped_reason:
anyOf:
- type: string
- type: 'null'
description: Why an enrichment run skipped this cell, when it did.
title: Skipped Reason
stale:
default: false
description: Whether the value is out of date and awaits a recompute.
title: Stale
type: boolean
updated_at:
description: When this cell was last written.
format: date-time
title: Updated At
type: string
value:
description: The cell's value; null renders the column default.
title: Value
version:
description: Per-cell watermark; apply only if at least the cached one.
title: Version
type: integer
waiting_on:
anyOf:
- type: string
- type: 'null'
description: What a pending cell handed to a sender's LinkedIn browser waits for.
title: Waiting On
required:
- value
- error
- version
- updated_at
title: TableCellDeltaSchema
type: object
TableCellActivityStepSchema:
description: 'One agent research step, JSON-native.
Plain strings rather than the agent domain''s enums: this package sits
below ``table_agent`` and cannot import it, exactly like
``TableRunRowScopeSchema.kind``. ``action`` values today are ``search`` |
``map`` | ``scrape`` | ``crawl`` | ``mcp_tool`` | ``finish``; ``outcome``
values are ``completed`` | ``failed`` | ``refused`` | ``stopped``, the
same set ``core.ai.AiStep`` spells. Clients must tolerate new tokens.'
properties:
action:
title: Action
type: string
detail:
description: 'The search query, target URL, or tool call: the step''s input.'
title: Detail
type: string
duration_ms:
anyOf:
- type: integer
- type: 'null'
title: Duration Ms
observation:
description: One line on what came back.
title: Observation
type: string
outcome:
default: completed
title: Outcome
type: string
thought:
anyOf:
- type: string
- type: 'null'
description: The model's stated reasoning for choosing this step.
title: Thought
required:
- action
- detail
- observation
title: TableCellActivityStepSchema
type: object
TableRowDeltaSchema:
description: 'One row''s change, as a PARTIAL patch over its cells.
``cells`` carries only the columns this write touched, so a compute page''s
frame is proportional to the columns computed rather than to the table''s
width. Clients merge, never replace.
There is no row-level version and no cleared list. Each cell carries its
own monotonic watermark, so a delta applies per cell and applying one twice
or out of order is a no-op; and a cleared cell is PRESENT with a null value
rather than absent, so a partial map expresses a clear on its own.'
properties:
cells:
additionalProperties:
$ref: '#/components/schemas/TableCellDeltaSchema'
description: Only the columns this write touched, keyed by str(column_id).
title: Cells
type: object
record_id:
format: uuid
title: Record Id
type: string
required:
- record_id
- cells
title: TableRowDeltaSchema
type: object
TableRunRowScopeSchema:
description: 'The rows a run resolved to, so a reader can mark exactly those cells busy.
``kind`` is a plain string rather than the run domain''s enum: this package
sits under the table stratum and cannot import from it, which is also why
``trigger`` and ``status`` above are strings. Its values are
``all_rows`` | ``record_ids`` | ``unlisted`` | ``all_but``; the first and
third both mean "assume every row", and the last every row but
``excluded_record_ids``.'
properties:
excluded_record_ids:
description: The rows an all_but run leaves out; empty for every other kind.
items:
format: uuid
type: string
title: Excluded Record Ids
type: array
kind:
title: Kind
type: string
record_ids:
anyOf:
- items:
format: uuid
type: string
type: array
- type: 'null'
description: The exact rows the run will touch; populated for the record_ids kind only.
title: Record Ids
rows:
anyOf:
- type: integer
- type: 'null'
description: Rows the resolved scope covers; None for all rows.
title: Rows
required:
- kind
title: TableRunRowScopeSchema
type: object
TableHelloEventSchema:
description: 'Opening frame: the stream is live and the client should resync once.'
properties:
heartbeat_seconds:
description: Idle heartbeat cadence; treat silence beyond a small multiple as death.
title: Heartbeat Seconds
type: integer
kind:
const: hello
default: hello
title: Kind
type: string
table_id:
format: uuid
title: Table Id
type: string
required:
- table_id
- heartbeat_seconds
title: TableHelloEventSchema
type: object
TableRowsInvalidatedEventSchema:
description: 'The row SET changed (rows created or deleted). Refetch the page.
Membership and ordering changed, and a keyset window cannot be patched
locally, so this is deliberately an invalidation rather than a delta.'
properties:
kind:
const: rows_invalidated
default: rows_invalidated
title: Kind
type: string
record_ids:
anyOf:
- items:
format: uuid
type: string
type: array
- type: 'null'
description: The affected rows when known; null for a whole-table drain or a degraded batch.
title: Record Ids
row_count:
description: The table's authoritative row count after the change.
title: Row Count
type: integer
table_id:
format: uuid
title: Table Id
type: string
required:
- table_id
- row_count
title: TableRowsInvalidatedEventSchema
type: object
securitySchemes:
APIKeyHeader:
in: header
name: X-API-Key
type: apiKey
HTTPBearer:
scheme: bearer
type: http