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

# Create a monitor

> Create a condition on data that posts to your notification channels when it occurs

export const MonitorsExperimental = () => <Warning>
    <strong>Monitors is experimental.</strong> Request and payload shapes can change without a deprecation window. Monitors isn't recommended for production workflows.
  </Warning>;

<MonitorsExperimental />

## Notes

* To authenticate, you'll need a [Tako API key](https://tako.com/console/api-keys). It's best practice to store it as an environment variable to avoid hardcoding sensitive credentials in your code.
* `type` names a registered monitor type and `parameters` is validated against that type's schema. Read [List monitor types](/api-reference/monitor-types) first, and build `parameters` from the type's `parameters_schema`.
* Every `channel_ids` entry must name a channel you own, so [create the channel](/api-reference/notification-channels-create) before the monitor. An id that names no channel of yours answers `404`.
* `name` is your label. Tako never fills one in and never reads it.
* `fire_once` defaults to `true`, which pauses the monitor after its first firing. Set it `false` to fire on every new occurrence — a type that reports `fire_once_only` refuses that.
* `active_from` defaults to the moment of creation. `active_until` must be in the future and after `active_from`.

<Warning>
  **A monitor never fires for something that already happened.** A firing needs an occurrence that happens after the monitor exists, so creating a monitor is not a way to query history. Each type's `lookback_seconds` in [List monitor types](/api-reference/monitor-types) says how far back an occurrence may have happened and still fire, and its `description` says how long its source takes to report one.
</Warning>

## Check the resolved subject

The `201` is the **only** response that carries `resolved` — the subject the type matched from your parameters, such as the listing a ticker named. [Get a monitor](/api-reference/monitors-get) and [List monitors](/api-reference/monitors-list) don't return it. Read it here and confirm the monitor watches what you meant before you rely on it.

## When the subject is ambiguous

A `400` returns a `MonitorCreateRejected` with an `error_type`:

* `AMBIGUOUS_SUBJECT` — your parameters could have meant more than one subject. `candidates` lists every one, best first. Narrow the parameters and retry.
* `BAD_REQUEST` — anything else. `candidates` is empty.


## OpenAPI

````yaml POST /v1/monitors
openapi: 3.1.0
info:
  title: Knowledge Search API
  version: 1.0.0
servers:
  - url: https://tako.com/api/
    description: Tako Production API Server
security: []
paths:
  /v1/monitors:
    post:
      tags:
        - monitors
      summary: Create a monitor
      description: >-
        Create a condition on data. The type names a registered monitor type and
        the parameters are validated against that type's schema. Occurrences
        older than the monitor never fire: a firing needs an occurrence that
        happens after the monitor exists. Each type's schema in listMonitorTypes
        says what counts as an occurrence and how long its source takes to
        report one. Every channel_ids entry must name a channel you own; one
        that doesn't answers 404. When the parameters name more than one
        subject, the 400 lists the candidates.


        **Experimental.** Request and payload shapes can change without a
        deprecation window. Monitors isn't recommended for production workflows.
      operationId: createMonitor
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MonitorCreate'
        required: true
      responses:
        '201':
          description: >-
            The created monitor, with the resolved subject this response alone
            returns
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitorCreated'
        '400':
          description: Invalid request, or an ambiguous subject with its candidates.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitorCreateRejected'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BaseAPIError'
        '404':
          description: A channel_ids entry names no channel belonging to the caller.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BaseAPIError'
      security:
        - apiKey: []
components:
  schemas:
    MonitorCreate:
      properties:
        name:
          type: string
          maxLength: 255
          title: Name
          description: >-
            Your label for the monitor. Tako never fills one in, and never reads
            it.
          default: ''
        type:
          type: string
          maxLength: 64
          title: Type
          description: >-
            A registered monitor type name, domain.subtype, for example
            stocks.pct_change.
        parameters:
          additionalProperties: true
          type: object
          title: Parameters
          description: Validated against the type's parameter schema.
        fire_once:
          type: boolean
          title: Fire Once
          description: >-
            Pause the monitor after its first firing. Set false to fire on every
            new occurrence, which a type reporting fire_once_only refuses.
          default: true
        channel_ids:
          items:
            type: string
            format: uuid
          type: array
          maxItems: 20
          minItems: 1
          title: Channel Ids
        active_from:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Active From
          description: Ignore occurrences before this instant. Null means from creation.
        active_until:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Active Until
          description: >-
            Pause the monitor as expired after this instant. Null means no end.
            Must be after active_from and in the future.
      type: object
      required:
        - type
        - parameters
        - channel_ids
      title: MonitorCreate
    MonitorCreated:
      properties:
        id:
          type: string
          format: uuid
          title: Id
        name:
          type: string
          title: Name
        type:
          type: string
          title: Type
        parameters:
          additionalProperties: true
          type: object
          title: Parameters
        fire_once:
          type: boolean
          title: Fire Once
        status:
          $ref: '#/components/schemas/MonitorStatus'
        status_reason:
          anyOf:
            - $ref: '#/components/schemas/StatusReason'
            - type: 'null'
          description: >-
            Why Tako paused the monitor. Null while the monitor is active, and
            null when you paused it yourself.
        active_from:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Active From
        active_until:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Active Until
        last_evaluated_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Last Evaluated At
          description: >-
            When the evaluation rule last ran for this monitor. Null until the
            first evaluation.
        last_evaluation_outcome:
          anyOf:
            - $ref: '#/components/schemas/EvaluationOutcome'
            - type: 'null'
          description: >-
            How that evaluation ended. Null until the first evaluation, and null
            again after you resume a paused monitor, because the pause
            invalidated that verdict. An active monitor with no firings and a
            recent predates_monitor or before_window here is alive and waiting
            for an occurrence that happens after it was created. no_occurrence
            means the type read no occurrence, which includes finding no usable
            data to compare.
        channel_ids:
          items:
            type: string
            format: uuid
          type: array
          title: Channel Ids
        created_at:
          type: string
          format: date-time
          title: Created At
        updated_at:
          type: string
          format: date-time
          title: Updated At
        resolved:
          additionalProperties:
            $ref: '#/components/schemas/Scalar'
          type: object
          title: Resolved
          description: >-
            The subject the type resolved from your parameters, for example the
            listing a ticker named. Check it before trusting the monitor; this
            response is the only one that carries it.
      type: object
      required:
        - id
        - name
        - type
        - parameters
        - fire_once
        - status
        - status_reason
        - active_from
        - active_until
        - last_evaluated_at
        - last_evaluation_outcome
        - channel_ids
        - created_at
        - updated_at
        - resolved
      title: MonitorCreated
    MonitorCreateRejected:
      properties:
        error_message:
          type: string
          title: Error Message
        error_type:
          $ref: '#/components/schemas/MonitorCreateErrorType'
        candidates:
          items:
            additionalProperties:
              $ref: '#/components/schemas/Scalar'
            type: object
          type: array
          title: Candidates
          default: []
      type: object
      required:
        - error_message
        - error_type
      title: MonitorCreateRejected
      description: >-
        400 on createMonitor. When error_type is AMBIGUOUS_SUBJECT, candidates
        lists every

        subject the parameters could have meant, best first, so the caller
        narrows and retries;

        for any other error_type it's empty.
    BaseAPIError:
      properties:
        error_message:
          type: string
          title: Error Message
        error_type:
          $ref: '#/components/schemas/APIErrorType'
      type: object
      required:
        - error_message
        - error_type
      title: BaseAPIError
    MonitorStatus:
      type: string
      enum:
        - active
        - paused
      title: MonitorStatus
    StatusReason:
      type: string
      enum:
        - fired_once
        - unloadable
        - expired
        - completed
      title: StatusReason
    EvaluationOutcome:
      type: string
      enum:
        - fired
        - already_fired
        - no_occurrence
        - predates_monitor
        - outside_lookback
        - unloadable
        - completed
        - unknown_type
        - inactive
        - deleted
        - expired
        - before_window
        - crashed
      title: EvaluationOutcome
      description: >-
        How one evaluation of a monitor ended. `fired` wrote a firing, and
        `already_fired` found that occurrence already recorded. `no_occurrence`
        found the condition unmet. `predates_monitor` and `before_window` found
        an occurrence from before the monitor or its `active_from`, and
        `outside_lookback` found one too old to report. `expired`, `unloadable`
        and `unknown_type` name why the rule stopped before reading data,
        `completed` means the subject reached an end state that leaves the
        condition unreachable, and `crashed` means the type raised while reading
        it. `deleted` and `inactive` reach only the `monitors.evaluation`
        metric; neither is ever stored on a monitor row.
    Scalar:
      anyOf:
        - type: string
        - type: integer
        - type: number
        - type: boolean
        - type: 'null'
    MonitorCreateErrorType:
      type: string
      enum:
        - BAD_REQUEST
        - AMBIGUOUS_SUBJECT
      title: MonitorCreateErrorType
      description: >-
        Why createMonitor refused. Kept apart from APIErrorType so a value only
        createMonitor

        returns stays out of the SDK spec, which the monitors operations are
        deliberately absent

        from. createMonitor is `docs`-audience, so this enum does reach the docs
        reference.
    APIErrorType:
      type: string
      enum:
        - BAD_REQUEST
        - AUTHENTICATION_ERROR
        - INTERNAL_SERVER_ERROR
        - RELEVANT_RESULTS_NOT_FOUND
        - RATE_LIMIT_EXCEEDED
        - PAYMENT_REQUIRED
        - REQUEST_TIMEOUT
        - FORBIDDEN
        - NOT_FOUND
        - SERVICE_UNAVAILABLE
        - SERVICE_OVERLOADED
        - UNSUPPORTED_CONTENT_FORMAT
      title: APIErrorType
  securitySchemes:
    apiKey:
      type: apiKey
      name: X-API-Key
      in: header

````