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

# Execute a SemQL semantic search query

> Compiles the SemQL query, embeds any text anchors, evaluates matches
across the namespace, and returns ranked results.

If the request omits `limit`, the limit is taken from the SemQL
`LIMIT n` clause when present.

Requires `Content-Type: application/json`.




## OpenAPI

````yaml /api/public-api.yaml post /v1/search
openapi: 3.0.3
info:
  title: Noetive Semantik API
  version: 0.4.0
  description: >
    Noetive Semantik is a managed semantic search and subscription service.

    Publish messages tagged with embedding vectors, query them with the

    SemQL query language, and subscribe to live match streams over

    Server-Sent Events.


    All request and response bodies are JSON. The `/v1/subscribe` endpoint

    accepts a JSON POST request and upgrades the response to an SSE stream

    of match events.


    ## Request decoding


    Every JSON endpoint decodes strictly. A request is rejected with

    `400 invalid_request` when the body is empty, is not valid JSON,

    **carries a field this specification does not define**, or carries

    trailing content after the first JSON value. Unknown fields are an

    error rather than being ignored, so a misspelled field name fails

    loudly instead of silently taking a default.


    ## SemQL query limits


    These bound the `query` field on `/v1/search`, `/v1/subscribe`, and

    `/v1/lint`. Search and subscribe reject an over-limit query with

    `400 invalid_request` while parsing it — before any anchor is embedded,

    so a rejected query is not billed for embedding. `/v1/lint` reports the

    same problems as diagnostics with `valid: false` and a `200`, which

    makes it the cheap way to check a generated query before sending it.


    | limit | value |

    | --- | --- |

    | anchors per query, across all clauses | 32 |

    | anchors in one list (`DIRECTION` toward, `ATTRACT`, `REPEL`) | 8 |

    | namespace names in `NAMESPACE` | 8 |

    | namespace names in the `NOT` exclusion list | 8 |

    | floats in one vector anchor | 4096 |

    | floats across all vector anchors in one query | 8192 |

    | anchor text plus namespace names, combined | 4 KB |

    | nodes per query (clauses plus boolean operators) | 64 |

    | operands per `AND` or `OR` | 16 |

    | parenthesis nesting depth | 128 |


    Value ranges: `WITHIN` in `[0, 1]`, `CONE` in `[0, π]` radians, `LIMIT`

    and `WINDOW` strictly positive. `WITHIN` and `TOP` are mutually

    exclusive on one clause. `LIMIT` is the exception to the reject rule —

    see `SearchRequest.limit`.


    ## Request correlation


    Every response — success or error — carries an `X-Request-Id` header

    with a server-assigned correlation token. Error response bodies repeat

    the same value in the `request_id` field so it survives client-side

    logging that strips headers. Quote `request_id` when contacting

    support; it pivots directly to the corresponding server log line.


    Inbound `X-Request-Id` headers from clients are ignored — the server

    assigns the value authoritatively to prevent log injection. When the

    request carries an `X-Amzn-Trace-Id` header, its `Root=` segment is

    used as the request id so upstream trace correlation works without

    translation. Otherwise a fresh server-side identifier is minted.


    ## Error codes


    Error responses carry a stable machine-readable `error` code, an

    optional human-readable `message`, the server-assigned `request_id`,

    and (for retryable failures) a `retry_after_ms` hint. Known codes:


    | code | meaning |

    | --- | --- |

    | `invalid_request` | request body failed validation |

    | `unauthorized` | missing or invalid bearer token |

    | `not_found` | no endpoint at the request path — check the base URL; do not
    retry |

    | `idempotency_key_conflict` | the `idempotency_key` is live from an earlier
    publish carrying different content; nothing was stored |

    | `unsupported_media_type` | `Content-Type` is not `application/json` |

    | `request_too_large` | request body exceeds the endpoint size limit |

    | `rate_limited` | per-client burst or rate limit exhausted |

    | `too_many_requests` | concurrency limit exhausted, or the namespace is at
    its concurrent-subscription cap |

    | `unavailable` | service temporarily unavailable; retry after
    `retry_after_ms` |

    | `namespace_unavailable` | namespace lookup is transiently unavailable;
    retry after `retry_after_ms` |

    | `namespace_disabled` | the namespace alias exists but has been
    administratively disabled |

    | `model_not_provisioned` | the namespace alias exists but has no entry for
    the requested (model, dimensions) combination |

    | `not_billable` | no active subscription on the account; resolve billing
    before retrying |

    | `metering_unavailable` | metered billing is transiently unavailable; retry
    with backoff |

    | `internal_error` | unexpected server error — quote `request_id` when
    contacting support |
  contact:
    name: Noetive Support
    url: https://noetive.io
    email: support@noetive.io
  license:
    name: Noetive Commercial
    url: https://noetive.io/terms
servers:
  - url: https://semantik.noetive.io
    description: Global Semantik endpoint
security:
  - bearerAuth: []
tags:
  - name: Search
    description: Run a SemQL query against published messages.
  - name: Publish
    description: Ingest messages with embedding vectors.
  - name: Subscribe
    description: Open a live SSE stream of matches for a SemQL query.
  - name: Tooling
    description: Query authoring helpers (lint, auto-complete).
  - name: Health
    description: Liveness probe.
paths:
  /v1/search:
    post:
      tags:
        - Search
      summary: Execute a SemQL semantic search query
      description: |
        Compiles the SemQL query, embeds any text anchors, evaluates matches
        across the namespace, and returns ranked results.

        If the request omits `limit`, the limit is taken from the SemQL
        `LIMIT n` clause when present.

        Requires `Content-Type: application/json`.
      operationId: search
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchRequest'
            examples:
              textQuery:
                summary: Text anchor search
                value:
                  query: >-
                    MATCH DISTANCE("machine learning research") WITHIN 0.4 LIMIT
                    10
                  namespace: global
                  model: Qwen3-Embedding-4B
                  dimensions: 1024
      responses:
        '200':
          description: Ranked search results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
        '400':
          description: |
            Invalid request. `error` is one of:

            - `invalid_request` — malformed JSON, SemQL compile error,
              missing required field, malformed namespace, or unknown
              namespace alias.
            - `model_not_provisioned` — the namespace alias exists but has
              no entry for the requested (model, dimensions) combination.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Missing or invalid API key bearer token. `error` is `unauthorized`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '402':
          description: |
            Request is authenticated but billing blocks the call. `error` is
            `not_billable`: the account has no active subscription.
            Retrying will keep failing until billing is resolved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: |
            Namespace is administratively disabled. `error` is
            `namespace_disabled`. The alias resolves but has been turned
            off; retries do not help until the namespace is re-enabled.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '405':
          description: Method not allowed (only POST is accepted).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: >-
            Request body exceeds 1 MB size limit. `error` is
            `request_too_large`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '415':
          description: >-
            Content-Type must be application/json. `error` is
            `unsupported_media_type`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: |
            Rate limited or too many concurrent requests.
            Error codes: `rate_limited` or `too_many_requests`.
            `retry_after_ms` is set; clients should back off.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error. `error` is `internal_error`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: |
            Service is temporarily unavailable. `error` is one of:

            - `unavailable` — the service or one of its dependencies is
              transiently unavailable. Retry after `retry_after_ms`.
            - `namespace_unavailable` — namespace lookup is transiently
              unavailable.
            - `metering_unavailable` — metered billing is transiently
              unavailable; retry with exponential backoff.

            `retry_after_ms` is set on all of the above; the `Retry-After`
            header is populated alongside it.
          headers:
            Retry-After:
              description: Seconds to wait before retrying (RFC 9110).
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    SearchRequest:
      type: object
      required:
        - query
        - namespace
        - model
        - dimensions
      properties:
        query:
          type: string
          description: |
            Raw SemQL text submitted by the client. Subject to the SemQL
            query limits — see the "SemQL query limits" section in the API
            description.
        namespace:
          type: string
          maxLength: 64
          pattern: ^[A-Za-z0-9_-]+$
          description: |
            Target namespace alias — a registered name (e.g. `articles`) or
            the well-known `global` alias. Required; there is no default.
            Every request is validated against the namespace's configured
            model and dimensions; a mismatch returns `400 invalid_request`.

            Pass the alias, not the `ns_...` identifier shown in the
            dashboard — a raw identifier is rejected with
            `400 invalid_request`.
        model:
          type: string
          description: |
            Embedding model name. Required; there is no default. Must match
            the model configured on the namespace, or the request fails with
            `400 model_not_provisioned`.
        dimensions:
          type: integer
          minimum: 1
          maximum: 4096
          description: |
            Embedding vector dimensionality. Required; there is no default.
            Must match the dimensionality configured on the namespace for
            `model`, or the request fails with `400 model_not_provisioned`.
        limit:
          type: integer
          minimum: 1
          description: |
            Maximum number of results to return. Takes precedence over the
            SemQL `LIMIT n` clause; when both are omitted, 100 results are
            returned.

            Values above 1000 are **clamped to 1000, not rejected** — the
            request succeeds and returns at most 1000 results. A client that
            treats a successful response as "everything matched" will
            silently miss results. Narrow the `WINDOW` or tighten the query
            instead of raising the limit.
    SearchResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/ResultItem'
          description: Ranked list of matched documents.
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: |
            Machine-readable error code. See the "Error codes" table in the
            API description for the full list.
        message:
          type: string
          description: Human-readable error description.
        request_id:
          type: string
          description: |
            Server-assigned correlation token, also returned in the
            `X-Request-Id` response header. Quote this when contacting
            support — it pivots directly to the relevant server log line.
        retry_after_ms:
          type: integer
          format: uint32
          description: |
            Hint for how long to wait before retrying. Present on
            `backpressure`, `unavailable`, `namespace_unavailable`, and
            `metering_unavailable` errors; absent (or `0`) means do not
            retry.
    ResultItem:
      type: object
      properties:
        content:
          type: string
          description: |
            Message body of the matched document. Empty when the message was
            published as a vector with no `text`, which is legitimate — such a
            message is searchable and scoreable but has no body to return.
        message_id:
          type: string
          description: Stable, globally unique identifier of the matched message.
        namespace:
          type: string
          description: Namespace of the matched message.
        score:
          type: number
          format: float
          description: Composite relevance score.
        metadata:
          type: object
          description: |
            Key-value metadata attached at publish time. Same constraints
            as `PublishRequest.metadata`.
          additionalProperties:
            type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: |
        API key bearer token. Obtain from the Noetive dashboard.
        Pass as: `Authorization: Bearer <api-key>`.

````