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

# Push replica ops

> Ingest sealed replica ops from a device. Write permission when auth is on. Rejects unsealed E2EE ops.



## OpenAPI

````yaml /openapi.json post /v1/sync/ops
openapi: 3.1.0
info:
  description: >-
    HTTP contract for the current Fastify `/v1` surface. The vault is implicit:
    `Authorization: Bearer` binds `vault_id`; open locally when no auth is
    configured. Search and list return handles, provenance, and coverage — never
    full note bodies (use `GET /v1/notes/{note}` or `/raw`). Writes require
    `Idempotency-Key` and return a receipt (`applied` or `queued`). Create and
    PATCH embed `note` (GET shape without `lines`) when `status = applied`.
    Follow a queued receipt at `GET /v1/writes/{id}`. Errors are `{ error,
    message, statusCode, requestId, reason, hint, help, details[] }`. `reason`
    is UPPER_SNAKE (AIP-193 ErrorInfo.reason); `hint` is one imperative sentence
    naming the next request; `help` is a docs URL; `details` is the AIP-193 list
    (ErrorInfo, BadRequest, RetryInfo, QuotaFailure, Help). 401/403 on `/v1` and
    `/mcp` send RFC 6750 `WWW-Authenticate: Bearer realm="elanotes"`
    (`error=invalid_token` when a token was presented;
    `error=insufficient_scope` plus `scope` on 403). RFC 9728
    `/.well-known/oauth-protected-resource` is served when an issuer is
    configured. Abuse-protection rate limits (not cost metering) apply to `/v1`
    and `/mcp`. GET `/v1/*` and `/mcp` use `RATE_LIMIT_READ_PER_MINUTE` (default
    600). POST/PATCH/PUT/DELETE under `/v1` use `RATE_LIMIT_WRITE_PER_MINUTE`
    (default 60). `0` disables a policy. Responses carry IETF draft
    `RateLimit-Limit` / `RateLimit-Remaining` / `RateLimit-Reset`; every 429
    also has `Retry-After`. Reads are never metered for cost. This document does
    not invent `/v1/daily`, `/v1/tasks`, or `folder_id`; those are not
    registered routes. `GET /v1/tags` rolls up frontmatter tags. List filtering
    uses AIP-160 `filter` on GET `/v1/notes`, `/v1/search`, `/v1/grep`,
    `/v1/writes`, and `/v1/notes/{note}:listRevisions`. `PATCH
    /v1/notes/{note}?update_mask=` and `PATCH
    /v1/vault/write-settings?update_mask=` are AIP-161 field masks. Missing or
    unknown mask is `INVALID_UPDATE_MASK`. Canonical custom methods are AIP-136
    `:edit`, `:move`, `:rename`, `:rollback`, `:listRevisions`, `:approve`, and
    `:reject`. Legacy slash forms stay and send `Deprecation: true` plus `Link:
    rel="successor-version"`. Folder identity is a vault-relative `path` in the
    JSON body. `GET /openapi.json` is unauthenticated. Auth protects only `/v1`
    and `/mcp`.
  title: Ela Notes API
  version: 0.1.0
servers:
  - description: Production
    url: https://api.elanotes.com
  - description: Local
    url: http://127.0.0.1:4000
security:
  - bearer: []
tags:
  - description: >-
      Lexical (and optional hybrid) search plus grep. Results are handles plus
      coverage.
    name: Search
  - description: >-
      List by AIP-160 filter or legacy path prefix, plus line-sliced or raw
      reads. No folder_id query.
    name: Notes
  - description: >-
      Idempotent create, PATCH field-mask update, delete, and AIP-136
      :edit/:move/:rename. Applied create/PATCH receipts embed the note
      resource.
    name: Writes
  - description: One nested folder level. Identity is `path` in the body, not a folder id.
    name: Folders
  - description: >-
      List, presign, and multipart upload. Upload needs a vault working copy
      (`VAULT_PATH`).
    name: Attachments
  - description: 'Frontmatter tag rollup. Body #hashtags are not tags.'
    name: Tags
  - description: POST-only property aggregation. The list path is GET /v1/notes?filter=.
    name: Query
  - description: >-
      Pending-write queue (including GET /v1/writes/{id}), AIP-162 revisions,
      :rollback, :approve, :reject, and write settings. Reviewer permission when
      auth is on.
    name: Review
  - description: Index status and vault summary for the bound vault.
    name: Vault
  - description: >-
      Device replica plane (ops, snapshot, checkpoint, E2EE salt). Unchanged by
      the agentic API push.
    name: Sync
  - description: Streamable HTTP MCP on `/mcp` with the same auth plugin as `/v1`.
    name: MCP
  - description: >-
      Unauthenticated AuthKit bootstrap for native public clients. Token grants
      are proxied so the phone never holds WORKOS_API_KEY.
    name: Auth
  - description: Unauthenticated process and contract endpoints.
    name: Meta
paths:
  /v1/sync/ops:
    post:
      tags:
        - Sync
      summary: Push replica ops
      description: >-
        Ingest sealed replica ops from a device. Write permission when auth is
        on. Rejects unsealed E2EE ops.
      operationId: pushSyncOps
      requestBody:
        content:
          application/json:
            schema:
              additionalProperties: false
              properties:
                ops:
                  items:
                    additionalProperties: false
                    properties:
                      actor:
                        minLength: 1
                        type: string
                      deviceId:
                        minLength: 1
                        type: string
                      hlc:
                        additionalProperties: false
                        properties:
                          counter:
                            maximum: 9007199254740991
                            minimum: 0
                            type: integer
                          deviceId:
                            minLength: 1
                            type: string
                          physicalMs:
                            maximum: 9007199254740991
                            minimum: -9007199254740991
                            type: integer
                        required:
                          - physicalMs
                          - counter
                          - deviceId
                        type: object
                      noteId:
                        minLength: 1
                        type: string
                      opId:
                        minLength: 1
                        type: string
                      patches:
                        additionalProperties: false
                        properties:
                          body:
                            additionalProperties: false
                            properties:
                              from:
                                type: string
                              to:
                                type: string
                            required:
                              - from
                              - to
                            type: object
                          deleted:
                            additionalProperties: false
                            properties:
                              from:
                                type: boolean
                              to:
                                type: boolean
                            required:
                              - from
                              - to
                            type: object
                          slug:
                            additionalProperties: false
                            properties:
                              from:
                                type: string
                              to:
                                type: string
                            required:
                              - from
                              - to
                            type: object
                          tags:
                            additionalProperties: false
                            properties:
                              from:
                                type: string
                              to:
                                type: string
                            required:
                              - from
                              - to
                            type: object
                          title:
                            additionalProperties: false
                            properties:
                              from:
                                type: string
                              to:
                                type: string
                            required:
                              - from
                              - to
                            type: object
                        type: object
                      sealed:
                        type: boolean
                      visibility:
                        enum:
                          - standard
                          - e2ee
                        type: string
                    required:
                      - opId
                      - deviceId
                      - actor
                      - hlc
                      - noteId
                      - patches
                    type: object
                  maxItems: 500
                  minItems: 1
                  type: array
              required:
                - ops
              type: object
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                additionalProperties: false
                properties:
                  ops:
                    items:
                      additionalProperties: false
                      properties:
                        actor:
                          minLength: 1
                          type: string
                        createdAt:
                          type: string
                        deviceId:
                          minLength: 1
                          type: string
                        hlc:
                          additionalProperties: false
                          properties:
                            counter:
                              maximum: 9007199254740991
                              minimum: 0
                              type: integer
                            deviceId:
                              minLength: 1
                              type: string
                            physicalMs:
                              maximum: 9007199254740991
                              minimum: -9007199254740991
                              type: integer
                          required:
                            - physicalMs
                            - counter
                            - deviceId
                          type: object
                        noteId:
                          minLength: 1
                          type: string
                        opId:
                          minLength: 1
                          type: string
                        patches:
                          additionalProperties: false
                          properties:
                            body:
                              additionalProperties: false
                              properties:
                                from:
                                  type: string
                                to:
                                  type: string
                              required:
                                - from
                                - to
                              type: object
                            deleted:
                              additionalProperties: false
                              properties:
                                from:
                                  type: boolean
                                to:
                                  type: boolean
                              required:
                                - from
                                - to
                              type: object
                            slug:
                              additionalProperties: false
                              properties:
                                from:
                                  type: string
                                to:
                                  type: string
                              required:
                                - from
                                - to
                              type: object
                            tags:
                              additionalProperties: false
                              properties:
                                from:
                                  type: string
                                to:
                                  type: string
                              required:
                                - from
                                - to
                              type: object
                            title:
                              additionalProperties: false
                              properties:
                                from:
                                  type: string
                                to:
                                  type: string
                              required:
                                - from
                                - to
                              type: object
                          type: object
                        sealed:
                          type: boolean
                        seq:
                          maximum: 9007199254740991
                          minimum: -9007199254740991
                          type: integer
                        visibility:
                          enum:
                            - standard
                            - e2ee
                          type: string
                      required:
                        - opId
                        - deviceId
                        - actor
                        - hlc
                        - noteId
                        - patches
                        - seq
                        - createdAt
                      type: object
                    type: array
                required:
                  - ops
                type: object
          description: Default Response
          headers:
            RateLimit-Limit:
              description: >-
                IETF draft ceiling for this request's policy (read or write) in
                the current window.
              schema:
                type: integer
            RateLimit-Remaining:
              description: Requests remaining in the current window for this policy.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the current window resets.
              schema:
                type: integer
        '400':
          content:
            application/json:
              schema:
                additionalProperties: false
                properties:
                  details:
                    items:
                      additionalProperties: {}
                      properties:
                        '@type':
                          type: string
                      required:
                        - '@type'
                      type: object
                    type: array
                  error:
                    type: string
                  help:
                    type: string
                  hint:
                    type: string
                  message:
                    type: string
                  reason:
                    type: string
                  requestId:
                    type: string
                  statusCode:
                    maximum: 9007199254740991
                    minimum: -9007199254740991
                    type: integer
                required:
                  - error
                  - message
                  - statusCode
                  - requestId
                  - reason
                  - hint
                  - help
                  - details
                type: object
          description: Default Response
        '403':
          content:
            application/json:
              schema:
                additionalProperties: false
                properties:
                  details:
                    items:
                      additionalProperties: {}
                      properties:
                        '@type':
                          type: string
                      required:
                        - '@type'
                      type: object
                    type: array
                  error:
                    type: string
                  help:
                    type: string
                  hint:
                    type: string
                  message:
                    type: string
                  reason:
                    type: string
                  requestId:
                    type: string
                  statusCode:
                    maximum: 9007199254740991
                    minimum: -9007199254740991
                    type: integer
                required:
                  - error
                  - message
                  - statusCode
                  - requestId
                  - reason
                  - hint
                  - help
                  - details
                type: object
          description: Default Response
        '429':
          content:
            application/json:
              schema:
                additionalProperties: false
                properties:
                  details:
                    items:
                      additionalProperties: {}
                      properties:
                        '@type':
                          type: string
                      required:
                        - '@type'
                      type: object
                    type: array
                  error:
                    type: string
                  help:
                    type: string
                  hint:
                    type: string
                  message:
                    type: string
                  reason:
                    type: string
                  requestId:
                    type: string
                  statusCode:
                    maximum: 9007199254740991
                    minimum: -9007199254740991
                    type: integer
                required:
                  - error
                  - message
                  - statusCode
                  - requestId
                  - reason
                  - hint
                  - help
                  - details
                type: object
          description: Default Response
          headers:
            RateLimit-Limit:
              description: >-
                IETF draft ceiling for this request's policy (read or write) in
                the current window.
              schema:
                type: integer
            RateLimit-Remaining:
              description: Requests remaining in the current window for this policy.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the current window resets.
              schema:
                type: integer
            Retry-After:
              description: >-
                Seconds to wait before retrying. Present on every 429, including
                write-budget refusals.
              schema:
                type: integer
        '503':
          content:
            application/json:
              schema:
                additionalProperties: false
                properties:
                  details:
                    items:
                      additionalProperties: {}
                      properties:
                        '@type':
                          type: string
                      required:
                        - '@type'
                      type: object
                    type: array
                  error:
                    type: string
                  help:
                    type: string
                  hint:
                    type: string
                  message:
                    type: string
                  reason:
                    type: string
                  requestId:
                    type: string
                  statusCode:
                    maximum: 9007199254740991
                    minimum: -9007199254740991
                    type: integer
                required:
                  - error
                  - message
                  - statusCode
                  - requestId
                  - reason
                  - hint
                  - help
                  - details
                type: object
          description: Default Response
components:
  securitySchemes:
    bearer:
      description: >-
        Static bearer, WorkOS JWT, or open local when AUTH_REQUIRED is off and
        no static tokens are set. The token selects the vault; paths do not
        include vault_id.
      scheme: bearer
      type: http

````