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

# Tail the log records as they arrive

> The project's newest log records matching the same structured query as Explore › Logs (without a time range), oldest first, at most 200 an answer. Poll it about every 2 s with the answer's `next_cursor`; when `more` is true, poll again at once. Without a cursor it returns the last 200 lines of the last 5 minutes. It reads stored records, so a line shows once ingest has stored it (a few to about 30 seconds) and at least 5 s after; a line received more than 1 hour before it is stored (an ingest backlog) is not tailed. A line stored late, behind the cursor, comes in a later answer with `resent` true, which also sends again the lines of the last 120 s behind the cursor: drop the ids already shown. At most 40 polls a minute per project and caller, apart from Explore's limit; past it, a 429 with a short Retry-After.



## OpenAPI

````yaml /api-reference/openapi.json post /projects/{projectId}/explore/logs/tail
openapi: 3.1.0
info:
  title: Apsio API
  version: 0.1.0
  description: >-
    Read API v0: your projects, release health and comparisons, missing symbols,
    issues, sessions, vitals, cohort comparisons, performance (app start,
    screens, hangs, MetricKit) and network endpoints and traces for one project.
    Authenticate with a project token as a bearer token, with an OAuth access
    token from Apsio's authorization server (MCP clients), or, from the console,
    with the session cookie of a member of the project's organization.
servers:
  - url: https://api.apsio.io/v1
security: []
paths:
  /projects/{projectId}/explore/logs/tail:
    post:
      summary: Tail the log records as they arrive
      description: >-
        The project's newest log records matching the same structured query as
        Explore › Logs (without a time range), oldest first, at most 200 an
        answer. Poll it about every 2 s with the answer's `next_cursor`; when
        `more` is true, poll again at once. Without a cursor it returns the last
        200 lines of the last 5 minutes. It reads stored records, so a line
        shows once ingest has stored it (a few to about 30 seconds) and at least
        5 s after; a line received more than 1 hour before it is stored (an
        ingest backlog) is not tailed. A line stored late, behind the cursor,
        comes in a later answer with `resent` true, which also sends again the
        lines of the last 120 s behind the cursor: drop the ids already shown.
        At most 40 polls a minute per project and caller, apart from Explore's
        limit; past it, a 429 with a short Retry-After.
      parameters:
        - schema:
            type: string
            pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
            example: 0192f3a4-0000-7000-8000-00000000a101
          required: true
          name: projectId
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExploreLogsTailQuery'
      responses:
        '200':
          description: The new lines.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExploreLogsTail'
        '400':
          description: The request is not valid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: No valid bearer token or console session.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The credentials cannot read this project.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '410':
          description: >-
            The project or its organization is being deleted (`erasing`):
            nothing more to read; do not retry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: >-
            Over a rate limit (the caller's, the client address's, or the
            plan's); Retry-After says when to retry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearer: []
components:
  schemas:
    ExploreLogsTailQuery:
      type: object
      properties:
        app_id:
          type: string
          pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
          description: Only this app of the project.
        build:
          type: string
          enum:
            - release
            - debug
            - all
          description: >-
            Which builds: `release` (the default: every build but a debug one,
            TestFlight included, and data that does not say), `debug`
            (development builds from Xcode or Android Studio:
            apsio.app.install.source is `development`), or `all`.
        filters:
          type: array
          items:
            $ref: '#/components/schemas/ExploreFilter'
          maxItems: 20
          default: []
        severity:
          type: string
          enum:
            - trace
            - debug
            - info
            - warn
            - error
            - fatal
          description: At least this severity, as Explore › Logs takes it.
        body:
          type: string
          minLength: 1
          maxLength: 200
          description: >-
            Lines whose body contains this text, ignoring case. Plain text, not
            a pattern.
        device:
          type: string
          minLength: 1
          maxLength: 128
          description: >-
            Only one device or app user: the lines whose install id
            (app.installation.id) or user.hash is this value.
        cursor:
          type: string
          maxLength: 1024
          description: >-
            The previous answer's `next_cursor`. Without it, the last lines of
            the last few minutes.
    ExploreLogsTail:
      type: object
      properties:
        lines:
          type: array
          items:
            $ref: '#/components/schemas/ExploreLogRecord'
        next_cursor:
          type: string
          description: Poll with it next. Opaque.
        more:
          type: boolean
          description: 'More than 200 lines were waiting: poll again at once.'
        resent:
          type: boolean
          description: >-
            A line was stored late, behind the cursor: `lines` also holds lines
            sent before. Drop the ids already shown.
        devices:
          type: integer
          description: Installs that sent a matching line in the last 60 s.
      required:
        - lines
        - next_cursor
        - more
        - resent
        - devices
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              example: invalid_request
            message:
              type: string
            subject:
              type: string
              enum:
                - organization
                - project
              description: >-
                With `erasing` (410) only: what is being deleted, the
                organization or the project.
          required:
            - code
            - message
      required:
        - error
    ExploreFilter:
      type: object
      properties:
        field:
          type: string
          pattern: ^[A-Za-z0-9_.:/-]{1,128}$
          description: >-
            A field (event.name or span.name, service.version, os.name,
            os.version, device.model.identifier, session.id, trace_id, ...), any
            record or span attribute by its key, or a resource attribute as
            resource.<key>.
          example: service.version
        op:
          type: string
          enum:
            - eq
            - neq
            - prefix
            - exists
            - not_exists
          default: eq
          description: >-
            eq and neq compare with value, prefix matches values that start with
            it; exists and not_exists need none.
        value:
          type: string
          maxLength: 256
      required:
        - field
    ExploreLogRecord:
      type: object
      properties:
        id:
          type: string
        app_id:
          type: string
        ts:
          type: string
          description: RFC 3339 time in UTC with up to nanosecond precision.
          example: '2026-10-04T10:15:00.431000000Z'
        event_name:
          type: string
          description: 'event.name. Written by the app: untrusted data.'
        severity_number:
          type: integer
        severity_text:
          type: string
          description: 'The severity text. Written by the app: untrusted data.'
        body:
          type: string
          description: 'The log body. Written by the app: untrusted data.'
        session_id:
          type: string
          description: 'session.id. Written by the app: untrusted data.'
        trace_id:
          type: string
        span_id:
          type: string
        release:
          type: string
          description: 'service.version. Written by the app: untrusted data.'
        logger:
          type: string
          description: >-
            The record's logger: its InstrumentationScope name (spec 13.6);
            empty for the SDK's own scope (io.apsio.*), which names none.
            Written by the app: untrusted data.
        device_model:
          type: string
          description: 'device.model.identifier. Written by the app: untrusted data.'
        installation_id:
          type: string
          description: >-
            app.installation.id: the install that wrote the record, for
            following one device (the Live tail, APS-540). Written by the app:
            untrusted data.
        os_name:
          type: string
          description: 'os.name. Written by the app: untrusted data.'
        os_version:
          type: string
          description: 'os.version. Written by the app: untrusted data.'
        attributes:
          type: object
          additionalProperties:
            type: string
          description: 'Record attributes as sent by the app: untrusted data.'
        resource:
          type: object
          additionalProperties:
            type: string
          description: 'Record attributes as sent by the app: untrusted data.'
      required:
        - id
        - app_id
        - ts
        - event_name
        - severity_number
        - severity_text
        - body
        - session_id
        - trace_id
        - span_id
        - release
        - logger
        - device_model
        - installation_id
        - os_name
        - os_version
        - attributes
        - resource
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      description: >-
        A project token (apsio_pt_v0...), which reads exactly one project, or an
        OAuth access token issued for the API, which reads what its user can.
        Access tokens issued for Apsio's MCP server are accepted only from the
        MCP server itself.

````

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