> ## 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` is the name of a registered monitor type, and Tako validates `parameters` against that type's schema. Call [List monitor types](/api-reference/monitor-types) first, and build `parameters` from the type's `parameters_schema`.
* Every `channel_ids` entry must be a channel you own, so [create the channel](/api-reference/notification-channels-create) before the monitor. An id you don't own returns `404`.
* `channel_ids` is optional. A monitor with no channels records its firings, and you read them with [List a monitor's firings](/api-reference/monitors-firings). To add channels later, call [Update a monitor](/api-reference/monitors-update).
* `name` is your own label. Tako never fills one in, and never reads it.
* `fire_once` defaults to `true`, which pauses the monitor after its first firing. To fire on every new occurrence, set it to `false`. A type that reports `fire_once_only` rejects that.
* `active_from` defaults to the moment you create the monitor. `active_until` must be in the future and after `active_from`.
* You can hold a limited number of active monitors. When you're at that limit, this endpoint returns `400` with `error_type: LIMIT_REACHED`. See [Handle a rejected create](#handle-a-rejected-create).
* When the monitor fires, Tako posts to every channel you listed. For the request body, the headers, and how to verify the signature, see [Webhook deliveries](/documentation/integrating-tako/monitors/webhook-deliveries).

<Warning>
  **A monitor never fires for something that already happened.** A firing needs an occurrence that happens after you create the monitor, so you can't use a monitor to search 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 response holds `subject`: the subject the type matched from your parameters, such as the listing a ticker matched. Read it and confirm the monitor watches what you meant. Tako resolves the subject once, when you create the monitor, and never again. [Get a monitor](/api-reference/monitors-get) and [List monitors](/api-reference/monitors-list) return the same `subject`.

`parameters` comes back in the form this endpoint accepts, with names as Tako resolved them. A ticker you sent as `aapl` reads back as `AAPL`, with the exchange that Tako picked.

## Handle a rejected create

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

* `AMBIGUOUS_SUBJECT`: your parameters match more than one subject. `candidates` lists every one, best first. Narrow the parameters and retry.
* `LIMIT_REACHED`: you're at your active monitor limit. `limit` is your cap, and `error_message` says how to free a slot. Pause or delete a monitor you no longer need, or contact [support@tako.com](mailto:support@tako.com) about an enterprise limit.
* `BAD_REQUEST`: anything else. `candidates` is empty and `limit` is `null`.

Tako counts the active monitor limit per user, not pooled across an account. A monitor past its `active_until` doesn't count against it.


## 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. Set type to a registered monitor type, and
        Tako validates parameters against that type's schema. A monitor fires
        only for an occurrence that happens after you create it, so you can't
        use a monitor to search history. To find out what each type counts as an
        occurrence, and how long its source takes to report one, call
        listMonitorTypes. Every channel_ids entry must be a notification channel
        you own; otherwise the request returns 404. If the parameters match more
        than one subject, the 400 response 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 new monitor, in the same shape every later read returns
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitorResponse'
        '400':
          description: >-
            Invalid request, an ambiguous subject with its candidates, or you've
            reached your active monitor limit.
          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 isn't a notification channel you own.
          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: Tako validates these against the type's parameter schema.
        fire_once:
          type: boolean
          title: Fire Once
          description: >-
            Pause the monitor after its first firing. To fire on every new
            occurrence, set it to false, which a type that reports
            fire_once_only rejects.
          default: true
        channel_ids:
          items:
            type: string
            format: uuid
          type: array
          maxItems: 20
          title: Channel Ids
          description: >-
            Destinations to post each firing to. Empty means no delivery: the
            firings are still recorded and readable through listMonitorFirings.
        actions:
          items:
            additionalProperties: true
            type: object
          type: array
          maxItems: 5
          title: Actions
          description: >-
            What Tako does after the monitor fires, in order. Each entry is an
            object with kind, that kind's parameters, and optionally
            channel_ids. channel_ids sets where the action's output goes: leave
            it out to use the monitor's channels, list channels you own to use
            those, or send an empty list to keep the output in Tako. Actions
            aren't available yet, so a non-empty list returns 400.
        active_from:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Active From
          description: >-
            Ignore occurrences before this time. Null means from the moment you
            create the monitor.
        active_until:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Active Until
          description: >-
            Pause the monitor as expired after this time. Null means the monitor
            has no end. The value must be in the future and after active_from.
      type: object
      required:
        - type
        - parameters
      title: MonitorCreate
    MonitorResponse:
      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
          description: >-
            The parameters in the form createMonitor accepts, as this type's
            parameters_schema describes them. The ids Tako resolved them to
            never appear here. The names come back as Tako resolved them rather
            than as you typed them, so a stock monitor created with ticker aapl
            reads back ticker AAPL and the exchange MIC that resolution picked.
            A type whose input accepts more than one name for a subject can
            return a different one than you sent: a crypto monitor names the
            asset by coinmarketcap_id whichever name you created it with. A
            monitor Tako can no longer render against its type's current schema
            returns a reduced form; subject still names what it watches.
        subject:
          additionalProperties:
            $ref: '#/components/schemas/Scalar'
          type: object
          title: Subject
          description: >-
            The subject the type resolved from your parameters, such as the
            listing that a ticker matched, in the shape listMonitorTypes returns
            as subject_schema. Check it before you rely on the monitor. Tako
            resolves it once, when you create the monitor, and never re-resolves
            it, so it names what the monitor watches rather than what that
            subject is called today. Empty for a type that resolves no subject.
        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 Tako last evaluated 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 makes the
            earlier outcome meaningless. On an active monitor with no firings, a
            recent predates_monitor or before_window means the monitor is
            running and waiting for an occurrence that happens after you created
            it. no_occurrence means the type found no occurrence, which includes
            finding no usable data to compare.
        channel_ids:
          items:
            type: string
            format: uuid
          type: array
          title: Channel Ids
        actions:
          items:
            additionalProperties: true
            type: object
          type: array
          title: Actions
          description: >-
            The monitor's actions as Tako stored them: the fields you set on
            each action, and channel_ids only on an action where you set it. A
            field you left out takes the kind's default when the action runs.
            Empty for a monitor with no actions.
        created_at:
          type: string
          format: date-time
          title: Created At
        updated_at:
          type: string
          format: date-time
          title: Updated At
      type: object
      required:
        - id
        - name
        - type
        - parameters
        - subject
        - fire_once
        - status
        - status_reason
        - active_from
        - active_until
        - last_evaluated_at
        - last_evaluation_outcome
        - channel_ids
        - actions
        - created_at
        - updated_at
      title: MonitorResponse
    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: []
        limit:
          anyOf:
            - type: integer
            - type: 'null'
          title: Limit
      type: object
      required:
        - error_message
        - error_type
      title: MonitorCreateRejected
      description: >-
        The 400 response from createMonitor, createNotificationChannel, and
        patchMonitor. When

        error_type is AMBIGUOUS_SUBJECT, candidates lists every subject the
        parameters could have

        matched, best first, so you can narrow them and retry. When error_type
        is LIMIT_REACHED,

        limit is how many active monitors or notification channels you may hold.
        Tako counts that

        limit per user rather than pooling it across an account, and the message
        says how to free

        one, or where to ask for an enterprise limit. For any other error_type,
        candidates is empty

        and limit is null.
    BaseAPIError:
      properties:
        error_message:
          type: string
          title: Error Message
        error_type:
          $ref: '#/components/schemas/APIErrorType'
      type: object
      required:
        - error_message
        - error_type
      title: BaseAPIError
    Scalar:
      anyOf:
        - type: string
        - type: integer
        - type: number
        - type: boolean
        - type: 'null'
    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` recorded a firing, and
        `already_fired` found that occurrence already recorded. `no_occurrence`
        found the condition unmet, which includes finding no usable data to
        compare. `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` say
        why the evaluation stopped before it read any data. `completed` means
        the subject reached an end state, so the condition can never be met
        again, and `crashed` means the type failed while reading the data.
        `deleted` and `inactive` never appear on a monitor.
    MonitorCreateErrorType:
      type: string
      enum:
        - BAD_REQUEST
        - AMBIGUOUS_SUBJECT
        - LIMIT_REACHED
      title: MonitorCreateErrorType
      description: Why a monitors operation refused the request.
    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
        - PLACEHOLDER_CARD
        - VARIABLE_COST_NOT_REQUESTED
      title: APIErrorType
  securitySchemes:
    apiKey:
      type: apiKey
      name: X-API-Key
      in: header

````

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