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

# Create a signal definition

> Creates a definition and its first draft version, while signal definitions are switched on (503 otherwise). Both commit only after this answer is checked. A retry with the same Idempotency-Key and body replays the same answer for 24 hours instead of creating a second definition; a name already in use answers 409. The draft is not published: publishing stays with a person in the app.



## OpenAPI

````yaml https://api.enrik.ai/v1/openapi.json post /v1/signal-definitions
openapi: 3.1.2
info:
  title: Enrik API
  version: v1
  description: >-
    The public Enrik API, version 1. It is a server-to-server API: call it from
    your backend, never from a browser. It sends no CORS headers, and an
    `OPTIONS` request to an API path answers `405 method_not_allowed`.
    Authenticate with an API key sent as a Bearer token; each operation lists
    the scopes the key needs, and the `apiKey` security scheme says what each
    scope grants. Operations marked `x-stability-level: beta` may still change;
    `stable` ones change only in a new version. A query parameter or body field
    an operation does not declare is refused with `422 validation_error`, naming
    it. Every error answers the same envelope: branch on the HTTP status and
    `error.code`, whose known values `ErrorInfo` lists.
  contact:
    name: Enrik support
    email: support@enrik.ai
    url: https://docs.enrik.ai
servers:
  - url: https://api.enrik.ai
    description: Production
security: []
tags:
  - name: apiKeys
    description: >-
      API keys. Public, for any authenticated key: `GET /v1/me`, where it reads
      its own id, name, display prefix, expiry, workspace and scopes, and `POST
      /v1/me/rotate` and `POST /v1/me/revoke`, where it rotates its own secret
      or revokes itself. Minting, listing, rotating and revoking other keys is
      internal: an owner or admin does it in Settings → API keys.
  - name: companies
    description: >-
      Companies: the organisations in your workspace, with their contacts,
      timeline and where their facts came from.
  - name: companyCandidates
    description: >-
      Company candidates: companies a discovery job found, or a user added,
      waiting for review. Accept, reject (dismiss), archive and promote them,
      one at a time or in bulk.
  - name: companyDiscoveryJobs
    description: >-
      Company discovery jobs: searches for candidate companies from one source,
      with their candidates and a quality summary. Read-only here; running a job
      stays in the app.
  - name: companySignals
    description: >-
      Company signals: displayed signals about one company, with their evidence.
      Manual writes are internal session operations.
  - name: contacts
    description: 'Contacts: the people in your workspace, with their timeline.'
  - name: customFieldDefinitions
    description: >-
      Custom fields: the fields a workspace added to its contacts and companies,
      which their `customFields` hold by key.
  - name: discoveryBriefs
    description: >-
      Discovery briefs: how to find and judge companies for one ICP profile
      version, and their immutable versions. Read-only here.
  - name: exportFields
    description: >-
      The fields an export can carry, the workspace’s custom and recommendation
      fields included.
  - name: exportJobs
    description: >-
      CSV exports of companies, contacts and candidates: create a draft, preview
      it, start it, poll it and download the file. A key reads them with
      `exports:read` and runs them with `exports:run` and `crm:read`; delivery
      to a webhook destination stays in the app.
  - name: feedback
    description: >-
      Anonymous agent feedback about the public API. Any authenticated API key
      may send a note, which is stored with no sender; the report is an internal
      operator read.
  - name: health
    description: >-
      Whether the API is up: `GET /v1/health`, public and needing no API key, is
      the API catalog’s `status` link. The liveness and readiness probes for
      load balancers stay internal.
  - name: icpAssessments
    description: >-
      ICP assessments: how one company fares against an ICP profile version, as
      stored. Reading never evaluates.
  - name: icpProfiles
    description: >-
      ICP profiles: ideal customer profiles and the immutable versions that hold
      their criteria. Read-only here.
  - name: savedViews
    description: >-
      Saved views: named sets of filters, sort and columns over contacts or
      companies, which replay to the same records as the equivalent list query.
  - name: signalDefinitions
    description: >-
      Signal definitions: the signals the workspace looks for in companies, and
      the immutable versions that say what they are. Read-only here.
  - name: signalDetectors
    description: >-
      Signal detectors: the kinds of detector a signal definition can use, and
      why any cannot run.
  - name: webhookEventDeliveries
    description: 'The delivery log of webhook events: states and attempts, never a body.'
  - name: webhookEventTypes
    description: >-
      The webhook event types a subscription can name, and the permission and
      key scope each needs.
  - name: webhookSubscriptions
    description: >-
      Webhook subscriptions: which events Enrik sends, signed, to a receiver
      URL; edit, test, pause, resume and archive them, and rotate their signing
      secret. Owners and admins manage them, and grant `webhooks:write` to a
      key.
  - name: websiteOnboarding
    description: >-
      Workspace company setup: shared profile confirmation and durable command
      receipts. Public scoped setup operations and internal handoff/artifact
      projections.
  - name: workspaceMembers
    description: >-
      Workspace members: the people who use the workspace, as the user id and
      name a contact’s or company’s `ownerUserId` takes. Read-only.
externalDocs:
  description: Guides, authentication, errors, scopes and pagination.
  url: https://docs.enrik.ai
paths:
  /v1/signal-definitions:
    post:
      tags:
        - signalDefinitions
      summary: Create a signal definition
      description: >-
        Creates a definition and its first draft version, while signal
        definitions are switched on (503 otherwise). Both commit only after this
        answer is checked. A retry with the same Idempotency-Key and body
        replays the same answer for 24 hours instead of creating a second
        definition; a name already in use answers 409. The draft is not
        published: publishing stays with a person in the app.
      operationId: signalDefinitions.create
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignalDefinitionCreateRequest'
            example:
              name: Exhibits at a trade fair
              description: The company exhibits at a trade fair in its industry.
              body:
                name: Exhibits at a trade fair
                description: The company exhibits at a trade fair in its industry.
                humanExplanation: An exhibitor is investing in finding new customers this year.
                observableCondition: The company is on the fair’s published exhibitor list.
                examples:
                  - Listed as an exhibitor at the fair this year
                counterexamples:
                  - Only a visitor badge was mentioned
                evidenceRequirements:
                  permittedSourceKinds:
                    - controlled_directory
                  requireLocatedSupport: true
                  requireEntityAttribution: true
                  claimSupport:
                    requiredAssertion: affirmed
                    permittedModalities:
                      - factual
                  temporal:
                    semantics: condition_observed
                    minimumPrecision: year
                    windowDays: 365
                    allowPlannedFuture: true
                  coverage:
                    negativeEvidence: requires_certified_complete_scope
                detector:
                  kind: directory_listing
                  config:
                    sourceRole: exhibitor_list
                    editionLabel: '2026'
                subjectType: company
                temporalRule:
                  semantics: condition_observed
                  windowDays: 365
                  minimumPrecision: year
                  allowPlannedFuture: true
      responses:
        '201':
          description: A new signal definition together with its first draft version.
          headers:
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimitPolicy'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignalDefinitionCreated'
              example:
                definition:
                  id: 0199a1b2-0000-7000-8000-00000000f201
                  name: Exhibits at a trade fair
                  description: The company exhibits at a trade fair in its industry.
                  lifecycle: active
                  currentDraftVersionId: 0199a1b2-0000-7000-8000-00000000f211
                  currentPublishedVersionId: 0199a1b2-0000-7000-8000-00000000f211
                  revision: 1
                  createdBy: 0199a1b2-0000-7000-8000-00000000c001
                  updatedBy: 0199a1b2-0000-7000-8000-00000000c001
                  createdAt: '2026-09-10T08:00:00.000Z'
                  updatedAt: '2026-09-12T08:00:00.000Z'
                version:
                  id: 0199a1b2-0000-7000-8000-00000000f211
                  signalDefinitionId: 0199a1b2-0000-7000-8000-00000000f201
                  versionNumber: 1
                  body:
                    name: Exhibits at a trade fair
                    description: The company exhibits at a trade fair in its industry.
                    humanExplanation: >-
                      An exhibitor is investing in finding new customers this
                      year.
                    observableCondition: The company is on the fair’s published exhibitor list.
                    examples:
                      - Listed as an exhibitor at the fair this year
                    counterexamples:
                      - Only a visitor badge was mentioned
                    evidenceRequirements:
                      permittedSourceKinds:
                        - controlled_directory
                      requireLocatedSupport: true
                      requireEntityAttribution: true
                      claimSupport:
                        requiredAssertion: affirmed
                        permittedModalities:
                          - factual
                      temporal:
                        semantics: condition_observed
                        minimumPrecision: year
                        windowDays: 365
                        allowPlannedFuture: true
                      coverage:
                        negativeEvidence: requires_certified_complete_scope
                    detector:
                      kind: directory_listing
                      config:
                        sourceRole: exhibitor_list
                        editionLabel: '2026'
                    subjectType: company
                    temporalRule:
                      semantics: condition_observed
                      windowDays: 365
                      minimumPrecision: year
                      allowPlannedFuture: true
                  detectorKind: directory_listing
                  schemaVersion: 1
                  detectorContractVersion: 1
                  contentFingerprint: sha256:4e1a9c07
                  publicationStatus: draft
                  firstPublishedAt: null
                  publishedAt: null
                  retiredAt: null
                  createdBy: 0199a1b2-0000-7000-8000-00000000c001
                  createdAt: '2026-09-10T08:00:00.000Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableContent'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
        default:
          $ref: '#/components/responses/Error'
      security:
        - apiKey:
            - discovery:write
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: >-
        A key you choose for this request, such as a UUID. Retrying with the
        same key returns the first result instead of doing the work twice.
      schema:
        type: string
        minLength: 1
        maxLength: 200
  schemas:
    SignalDefinitionCreateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
          description: The definition’s name, unique among the live definitions.
        description:
          anyOf:
            - type: string
              maxLength: 2000
            - type: 'null'
          description: What the signal is about; `null` when not given.
        body:
          $ref: '#/components/schemas/SignalDefinitionContentRequest'
          description: The content of the first draft version.
      required:
        - name
        - description
        - body
      additionalProperties: false
      description: A new signal definition and the content of its first draft version.
    SignalDefinitionCreated:
      type: object
      properties:
        definition:
          $ref: '#/components/schemas/SignalDefinition'
          description: The new definition.
        version:
          $ref: '#/components/schemas/SignalDefinitionVersion'
          description: Its first version, a draft.
      required:
        - definition
        - version
      additionalProperties: true
      description: A new signal definition together with its first draft version.
    SignalDefinitionContentRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
          description: The signal’s name in this version.
        description:
          anyOf:
            - type: string
              maxLength: 2000
            - type: 'null'
          description: What the signal is about; `null` when not given.
        humanExplanation:
          type: string
          minLength: 1
          maxLength: 4000
          description: What the signal means, for a person.
        observableCondition:
          type: string
          minLength: 1
          maxLength: 4000
          description: What must be observed for the signal to hold.
        examples:
          maxItems: 10
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 1000
          description: Examples of the signal holding, at most 10.
        counterexamples:
          maxItems: 10
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 1000
          description: Examples of it not holding, at most 10.
        evidenceRequirements:
          $ref: '#/components/schemas/SignalEvidenceRequirementsRequest'
          description: What evidence must show before the signal holds.
        detector:
          $ref: '#/components/schemas/SignalDetectorSettingRequest'
          description: The detector that looks for the signal, and its settings.
        subjectType:
          type: string
          enum:
            - company
          description: 'What the signal is about: `company`.'
        temporalRule:
          $ref: '#/components/schemas/SignalTemporalRuleRequest'
          description: The window the signal must fall in.
      required:
        - name
        - description
        - humanExplanation
        - observableCondition
        - examples
        - counterexamples
        - evidenceRequirements
        - detector
        - subjectType
        - temporalRule
      additionalProperties: false
      description: >-
        What one version of a signal says. `evidenceRequirements.temporal`
        repeats `temporalRule` exactly, and
        `evidenceRequirements.coverage.negativeEvidence` is the one the detector
        allows.
    SignalDefinition:
      type: object
      properties:
        id:
          type: string
          description: The signal definition’s id.
        name:
          type: string
          description: The signal’s name.
        description:
          description: What the signal is about; `null` when not given.
          type:
            - string
            - 'null'
        lifecycle:
          type: string
          enum:
            - active
            - archived
          description: '`active`, or `archived` (kept for history, not for new use).'
        currentDraftVersionId:
          description: The version being drafted; `null` when there is no draft.
          type:
            - string
            - 'null'
        currentPublishedVersionId:
          description: The version in use; `null` until one is published.
          type:
            - string
            - 'null'
        revision:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: The definition’s revision, which every change to it increases.
        createdBy:
          description: The user who created the definition; `null` when no user did.
          type:
            - string
            - 'null'
        updatedBy:
          description: The user who last changed the definition; `null` when no user did.
          type:
            - string
            - 'null'
        createdAt:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
          description: When the definition was created.
        updatedAt:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
          description: When the definition last changed.
      required:
        - id
        - name
        - description
        - lifecycle
        - currentDraftVersionId
        - currentPublishedVersionId
        - revision
        - createdBy
        - updatedBy
        - createdAt
        - updatedAt
      additionalProperties: true
      description: >-
        A signal the workspace looks for in companies. What it says lives in its
        versions.
    SignalDefinitionVersion:
      type: object
      properties:
        id:
          type: string
          description: The version’s id.
        signalDefinitionId:
          type: string
          description: The signal definition the version belongs to.
        versionNumber:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: The version’s number, from 1, in the order they were made.
        body:
          $ref: '#/components/schemas/SignalDefinitionContent'
          description: What the version says. A version never changes.
        detectorKind:
          type: string
          enum:
            - directory_listing
            - page_extract_llm
            - stored_context_llm
          description: The kind of detector the version uses.
        schemaVersion:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: The version of the definition format.
        detectorContractVersion:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: The version of the detector contract it was made for.
        contentFingerprint:
          type: string
          description: A fingerprint of the body, equal for equal bodies.
        publicationStatus:
          type: string
          enum:
            - draft
            - published
            - retired
          description: '`draft`, `published`, or `retired` (never published again).'
        firstPublishedAt:
          anyOf:
            - type: string
              format: date-time
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
            - type: 'null'
          description: When the version was first published; `null` if never.
        publishedAt:
          anyOf:
            - type: string
              format: date-time
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
            - type: 'null'
          description: When the version was last published; `null` if never.
        retiredAt:
          anyOf:
            - type: string
              format: date-time
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
            - type: 'null'
          description: When the version was retired; `null` if not.
        createdBy:
          description: The user who made the version; `null` when no user did.
          type:
            - string
            - 'null'
        createdAt:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
          description: When the version was made.
      required:
        - id
        - signalDefinitionId
        - versionNumber
        - body
        - detectorKind
        - schemaVersion
        - detectorContractVersion
        - contentFingerprint
        - publicationStatus
        - firstPublishedAt
        - publishedAt
        - retiredAt
        - createdBy
        - createdAt
      additionalProperties: true
      description: One immutable version of a signal definition.
    ErrorEnvelope:
      type: object
      properties:
        error:
          $ref: '#/components/schemas/ErrorInfo'
          description: >-
            What went wrong: the code to branch on, a message and the request
            id.
      required:
        - error
      additionalProperties: true
      description: The body of every error response.
    SignalEvidenceRequirementsRequest:
      type: object
      properties:
        permittedSourceKinds:
          minItems: 1
          maxItems: 4
          type: array
          items:
            type: string
            enum:
              - controlled_directory
              - company_page
              - workspace_document
              - provider_record
          description: The kinds of source evidence may come from; at least one.
        requireLocatedSupport:
          type: boolean
          description: Whether evidence must point at where in the source it is.
        requireEntityAttribution:
          type: boolean
          const: true
          description: 'Evidence must be about the company itself: always `true`.'
        claimSupport:
          $ref: '#/components/schemas/SignalClaimSupportRequest'
          description: What a source’s claim must look like.
        temporal:
          anyOf:
            - $ref: '#/components/schemas/SignalEvidenceWindowRequest'
            - type: 'null'
          description: >-
            When evidence must date from: the same values as `temporalRule`,
            never `null`.
        coverage:
          $ref: '#/components/schemas/SignalEvidenceCoverageRequest'
          description: What an absence of evidence may be taken to mean.
      required:
        - permittedSourceKinds
        - requireLocatedSupport
        - requireEntityAttribution
        - claimSupport
        - temporal
        - coverage
      additionalProperties: false
      description: What evidence must show before the signal is said to hold.
    SignalDetectorSettingRequest:
      oneOf:
        - $ref: '#/components/schemas/SignalDirectoryListingDetectorRequest'
        - $ref: '#/components/schemas/SignalPageExtractDetectorRequest'
        - $ref: '#/components/schemas/SignalStoredContextDetectorRequest'
      description: How the signal is detected.
    SignalTemporalRuleRequest:
      type: object
      properties:
        semantics:
          type: string
          enum:
            - event_occurred
            - event_announced
            - condition_observed
          description: >-
            What the date is of: an event, its announcement, or an observed
            condition.
        windowDays:
          anyOf:
            - type: integer
              minimum: 1
              maximum: 3650
            - type: 'null'
          description: >-
            How many days back the signal may date from, 1 to 3650, or `null`
            for no limit.
        minimumPrecision:
          type: string
          enum:
            - day
            - month
            - year
          description: How exact the date must be at least.
        allowPlannedFuture:
          type: boolean
          description: Whether an event planned for later counts.
      required:
        - semantics
        - windowDays
        - minimumPrecision
        - allowPlannedFuture
      additionalProperties: false
      description: When the signal must have happened.
    SignalDefinitionContent:
      type: object
      properties:
        name:
          type: string
          description: The signal’s name in this version.
        description:
          description: What the signal is about; `null` when not given.
          type:
            - string
            - 'null'
        humanExplanation:
          type: string
          description: What the signal means, for a person.
        observableCondition:
          type: string
          description: What must be observed for the signal to hold.
        examples:
          type: array
          items:
            type: string
          description: Examples of the signal holding.
        counterexamples:
          type: array
          items:
            type: string
          description: Examples of it not holding.
        evidenceRequirements:
          $ref: '#/components/schemas/SignalEvidenceRequirements'
          description: What evidence must show before the signal holds.
        detector:
          $ref: '#/components/schemas/SignalDetectorSetting'
          description: The detector that looks for the signal, and its settings.
        subjectType:
          type: string
          enum:
            - company
          description: 'What the signal is about: a company.'
        temporalRule:
          $ref: '#/components/schemas/SignalTemporalRule'
          description: The window the signal must fall in.
      required:
        - name
        - description
        - humanExplanation
        - observableCondition
        - examples
        - counterexamples
        - evidenceRequirements
        - detector
        - subjectType
        - temporalRule
      additionalProperties: true
      description: What one version of a signal says.
    ErrorInfo:
      type: object
      properties:
        code:
          type: string
          x-extensible-enum:
            - malformed_json
            - invalid_sort
            - unauthenticated
            - insufficient_scope
            - permission_denied
            - beta_access_required
            - not_a_member
            - not_found
            - method_not_allowed
            - conflict
            - stale_version
            - idempotency_key_reused
            - request_in_flight
            - company_twin_research_already_running
            - company_twin_own_domain_conflict
            - concurrent_run_limit
            - gone
            - payload_too_large
            - unsupported_media_type
            - validation_error
            - rate_limited
            - internal_error
            - response_contract_violation
            - service_unavailable
          description: >-
            A stable, machine-readable code such as `not_found`. Branch on this,
            not on `message`. The known values are every code a public operation
            answers; more may be added, so handle an unknown one by its HTTP
            status.
        message:
          type: string
          description: A human-readable explanation. It may change; do not parse it.
        requestId:
          type: string
          description: >-
            The id of the request that failed. Quote it when you contact
            support.
        details:
          description: >-
            Structured detail for some codes. For `validation_error` it is
            usually an array with one entry per problem: `path` (the field,
            dotted), `message` and, where the case has a name, `code` (such as
            `related_record_not_found`). Other codes that cover several cases
            carry an object whose `code` names the case (such as
            `invalid_cursor`).
      required:
        - code
        - message
        - requestId
      additionalProperties: true
      description: What went wrong.
    SignalClaimSupportRequest:
      type: object
      properties:
        requiredAssertion:
          type: string
          const: affirmed
          description: 'Always `affirmed`: a source affirms it.'
        permittedModalities:
          minItems: 1
          maxItems: 2
          type: array
          items:
            type: string
            enum:
              - factual
              - planned
          description: 'Which kinds of claim count: `factual`, and possibly `planned`.'
      required:
        - requiredAssertion
        - permittedModalities
      additionalProperties: false
      description: What a claim must look like to count.
    SignalEvidenceWindowRequest:
      type: object
      properties:
        semantics:
          type: string
          enum:
            - event_occurred
            - event_announced
            - condition_observed
          description: What the date is of; must equal `temporalRule.semantics`.
        minimumPrecision:
          type: string
          enum:
            - day
            - month
            - year
          description: >-
            How exact the date must be at least; must equal
            `temporalRule.minimumPrecision`.
        windowDays:
          anyOf:
            - type: integer
              minimum: 1
              maximum: 3650
            - type: 'null'
          description: >-
            How many days back evidence may date from, 1 to 3650, or `null` for
            no limit; must equal `temporalRule.windowDays`.
        allowPlannedFuture:
          type: boolean
          description: >-
            Whether an event planned for later counts; must equal
            `temporalRule.allowPlannedFuture`.
      required:
        - semantics
        - minimumPrecision
        - windowDays
        - allowPlannedFuture
      additionalProperties: false
      description: When evidence must date from.
    SignalEvidenceCoverageRequest:
      type: object
      properties:
        negativeEvidence:
          type: string
          enum:
            - requires_certified_complete_scope
            - never
          description: >-
            What it takes to say a company does NOT show the signal. Fixed by
            the detector: `requires_certified_complete_scope` for
            `directory_listing`, `never` for the others.
      required:
        - negativeEvidence
      additionalProperties: false
      description: When an absence of evidence means something.
    SignalDirectoryListingDetectorRequest:
      type: object
      properties:
        kind:
          type: string
          const: directory_listing
          description: The company is listed in a directory.
        config:
          $ref: '#/components/schemas/SignalDirectoryListingConfigRequest'
          description: How the directory is read.
      required:
        - kind
        - config
      additionalProperties: false
      description: Finds the signal in a controlled directory the company is listed in.
    SignalPageExtractDetectorRequest:
      type: object
      properties:
        kind:
          type: string
          const: page_extract_llm
          description: A model reads the company’s own pages.
        config:
          $ref: '#/components/schemas/SignalPageExtractConfigRequest'
          description: How the pages are read.
      required:
        - kind
        - config
      additionalProperties: false
      description: Finds the signal on the company’s own pages, read by a model.
    SignalStoredContextDetectorRequest:
      type: object
      properties:
        kind:
          type: string
          const: stored_context_llm
          description: >-
            A model reads what the workspace has stored. Research only: never
            publishable.
        config:
          $ref: '#/components/schemas/SignalStoredContextConfigRequest'
          description: How the stored context is read.
      required:
        - kind
        - config
      additionalProperties: false
      description: Finds the signal in what the workspace already knows about the company.
    SignalEvidenceRequirements:
      type: object
      properties:
        permittedSourceKinds:
          type: array
          items:
            type: string
            enum:
              - controlled_directory
              - company_page
              - workspace_document
              - provider_record
          description: The kinds of source evidence may come from.
        requireLocatedSupport:
          type: boolean
          description: Whether evidence must point at where in the source it is.
        requireEntityAttribution:
          type: boolean
          const: true
          description: 'Evidence must be about the company itself: always `true`.'
        claimSupport:
          $ref: '#/components/schemas/SignalClaimSupport'
          description: What a source’s claim must look like.
        temporal:
          anyOf:
            - $ref: '#/components/schemas/SignalEvidenceWindow'
            - type: 'null'
          description: When evidence must date from; `null` when any date will do.
        coverage:
          $ref: '#/components/schemas/SignalEvidenceCoverage'
          description: What an absence of evidence may be taken to mean.
      required:
        - permittedSourceKinds
        - requireLocatedSupport
        - requireEntityAttribution
        - claimSupport
        - temporal
        - coverage
      additionalProperties: true
      description: What evidence must show before the signal is said to hold.
    SignalDetectorSetting:
      oneOf:
        - $ref: '#/components/schemas/SignalDirectoryListingDetector'
        - $ref: '#/components/schemas/SignalPageExtractDetector'
        - $ref: '#/components/schemas/SignalStoredContextDetector'
      description: How the signal is detected.
    SignalTemporalRule:
      type: object
      properties:
        semantics:
          type: string
          enum:
            - event_occurred
            - event_announced
            - condition_observed
          description: >-
            What the date is of: an event, its announcement, or an observed
            condition.
        windowDays:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: How many days back the signal may date from; `null` for no limit.
        minimumPrecision:
          type: string
          enum:
            - day
            - month
            - year
          description: How exact the date must be at least.
        allowPlannedFuture:
          type: boolean
          description: Whether an event planned for later counts.
      required:
        - semantics
        - windowDays
        - minimumPrecision
        - allowPlannedFuture
      additionalProperties: true
      description: When the signal must have happened.
    SignalDirectoryListingConfigRequest:
      type: object
      properties:
        sourceRole:
          type: string
          minLength: 1
          maxLength: 120
          description: The role the company must hold in the list, such as `exhibitor`.
        editionLabel:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 120
            - type: 'null'
          description: >-
            Which edition of the directory, such as a year; `null` for a rolling
            directory.
      required:
        - sourceRole
        - editionLabel
      additionalProperties: false
      description: How a directory listing is read.
    SignalPageExtractConfigRequest:
      type: object
      properties:
        announcementType:
          type: string
          minLength: 1
          maxLength: 120
          description: What kind of announcement to look for.
        maxPagesPerCompany:
          type: number
          const: 1
          description: 'How many pages of each company to read: always 1.'
      required:
        - announcementType
        - maxPagesPerCompany
      additionalProperties: false
      description: How a company’s pages are read.
    SignalStoredContextConfigRequest:
      type: object
      properties:
        note:
          anyOf:
            - type: string
              maxLength: 500
            - type: 'null'
          description: A note on what to look for; `null` when none.
      required:
        - note
      additionalProperties: false
      description: How stored context is read.
    SignalClaimSupport:
      type: object
      properties:
        requiredAssertion:
          type: string
          const: affirmed
          description: 'What a source must do with the claim: affirm it.'
        permittedModalities:
          type: array
          items:
            type: string
            enum:
              - factual
              - planned
          description: 'Which kinds of claim count: a fact, and possibly a plan.'
      required:
        - requiredAssertion
        - permittedModalities
      additionalProperties: true
      description: What a claim must look like to count.
    SignalEvidenceWindow:
      type: object
      properties:
        semantics:
          type: string
          enum:
            - event_occurred
            - event_announced
            - condition_observed
          description: >-
            What the date is of: an event, its announcement, or an observed
            condition.
        minimumPrecision:
          type: string
          enum:
            - day
            - month
            - year
          description: How exact the date must be at least.
        windowDays:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: How many days back evidence may date from; `null` for no limit.
        allowPlannedFuture:
          type: boolean
          description: Whether an event planned for later counts.
      required:
        - semantics
        - minimumPrecision
        - windowDays
        - allowPlannedFuture
      additionalProperties: true
      description: When evidence must date from.
    SignalEvidenceCoverage:
      type: object
      properties:
        negativeEvidence:
          type: string
          enum:
            - requires_certified_complete_scope
            - never
          description: What it takes to say a company does NOT show the signal.
      required:
        - negativeEvidence
      additionalProperties: true
      description: When an absence of evidence means something.
    SignalDirectoryListingDetector:
      type: object
      properties:
        kind:
          type: string
          const: directory_listing
          description: The company is listed in a directory.
        config:
          $ref: '#/components/schemas/SignalDirectoryListingConfig'
          description: How the directory is read.
      required:
        - kind
        - config
      additionalProperties: true
      description: Finds the signal in a controlled directory the company is listed in.
    SignalPageExtractDetector:
      type: object
      properties:
        kind:
          type: string
          const: page_extract_llm
          description: A model reads the company’s own pages.
        config:
          $ref: '#/components/schemas/SignalPageExtractConfig'
          description: How the pages are read.
      required:
        - kind
        - config
      additionalProperties: true
      description: Finds the signal on the company’s own pages, read by a model.
    SignalStoredContextDetector:
      type: object
      properties:
        kind:
          type: string
          const: stored_context_llm
          description: A model reads what the workspace has stored.
        config:
          $ref: '#/components/schemas/SignalStoredContextConfig'
          description: How the stored context is read.
      required:
        - kind
        - config
      additionalProperties: true
      description: Finds the signal in what the workspace already knows about the company.
    SignalDirectoryListingConfig:
      type: object
      properties:
        sourceRole:
          type: string
          description: What part the directory plays, such as an exhibitor list.
        editionLabel:
          description: Which edition of the directory, such as a year; `null` when any.
          type:
            - string
            - 'null'
      required:
        - sourceRole
        - editionLabel
      additionalProperties: true
      description: How a directory listing is read.
    SignalPageExtractConfig:
      type: object
      properties:
        announcementType:
          type: string
          description: What kind of announcement to look for.
        maxPagesPerCompany:
          type: number
          const: 1
          description: >-
            How many pages of each company to read: one, in this contract
            version.
      required:
        - announcementType
        - maxPagesPerCompany
      additionalProperties: true
      description: How a company’s pages are read.
    SignalStoredContextConfig:
      type: object
      properties:
        note:
          description: A note on what to look for; `null` when none.
          type:
            - string
            - 'null'
      required:
        - note
      additionalProperties: true
      description: How stored context is read.
  headers:
    RateLimit:
      description: >-
        What the API key has left under each rate-limit policy that counted this
        request: a Structured Field list with one
        `"<policy>";r=<remaining>;t=<seconds>` item per policy. Read it as a
        list and honour every item, not only the smallest: continued traffic
        must satisfy each policy. `t` is the effective window in seconds (IETF
        RateLimit header fields, draft 11): quota is not guaranteed to be fully
        restored when it ends. When the answer also carries `Retry-After`, that
        takes priority. One policy counts this operation: `api-key`, every
        request the key makes.
      schema:
        type: string
      example: '"api-key";r=599;t=60'
    RateLimitPolicy:
      description: >-
        The rate-limit policies that counted this request: a Structured Field
        list with one `"<policy>";q=<requests>;w=<window in seconds>` item per
        policy. The limits belong to the key, not to the address it calls from.
        One policy counts this operation: `api-key`, every request the key
        makes.
      schema:
        type: string
      example: '"api-key";q=600;w=60'
    RetryAfter:
      description: >-
        Seconds to wait before retrying. It takes priority over the `t` of every
        `RateLimit` item.
      schema:
        type: integer
        minimum: 1
      example: 60
  responses:
    BadRequest:
      description: >-
        The request could not be read. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `malformed_json`: The body is not valid JSON, or is empty while
        `Content-Type` is `application/json`. Send valid JSON; omit
        `Content-Type` when there is no body.

        - `invalid_sort`: A sort names a field or direction the list does not
        support. Sort only by the fields the operation lists.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: malformed_json
              message: Bad Request
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    Unauthorized:
      description: >-
        The request is not authenticated. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `unauthenticated`: The key is missing, invalid, expired or revoked.
        Send a valid, unexpired key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: unauthenticated
              message: Unauthorized
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    Forbidden:
      description: >-
        The caller may not do this. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `insufficient_scope`: The key lacks a scope the operation, or a
        parameter such as `include` or `rankingMode`, needs.
        `details.missingScopes` names it; `WWW-Authenticate` lists every scope
        the request needs. Create a key with the missing scope.

        - `permission_denied`: The key’s scopes admit the operation, but its
        permissions do not cover this request: replaying a create needs
        `crm:read`, and a key keeps the permissions its scopes had when it was
        created. The message names the scope. Create a new key with the scope
        the message names.

        - `beta_access_required`: The workspace is not admitted to the beta,
        which every write except `feedback.submit` needs. Contact support.

        - `not_a_member`: `websiteOnboarding.getAccess`: the key’s workspace has
        been deleted. Use a key of a live workspace.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: insufficient_scope
              message: Forbidden
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    Conflict:
      description: >-
        The request conflicts with the current state. Branch on `error.code`;
        quote `error.requestId` to support.


        The codes a public operation answers with it:


        - `conflict`: The request clashes with the current state, such as a
        duplicate domain or e-mail, a changed setup or a ranked list that
        changed. `details.code` names the case where there is one. Read fresh
        state, then decide.

        - `stale_version`: The record changed since the `expectedUpdatedAt` you
        sent. `details.currentUpdatedAt` is its current version. Read the record
        again and reapply your change.

        - `idempotency_key_reused`: The `Idempotency-Key` was used for a
        different command or body. Use a new key for a new command.

        - `request_in_flight`: The first request with this `Idempotency-Key` is
        still running. Retry shortly with the same key.

        - `company_twin_research_already_running`:
        `websiteOnboarding.confirmProfile`: research for this setup or website
        is already running. Read fresh setup state.

        - `company_twin_own_domain_conflict`:
        `websiteOnboarding.confirmProfile`: the website does not match the
        workspace’s company profile. Read fresh setup state, then confirm the
        profile with its own website.

        - `concurrent_run_limit`: `companyDiscoveryJobs.start` by an API key:
        the workspace already has as many discovery jobs queued or running as a
        key may start beside. `details.code` names the cap. Wait for a job to
        finish, or cancel one, then start again.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: conflict
              message: Conflict
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    PayloadTooLarge:
      description: >-
        The body is over the size limit. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `payload_too_large`: The body is over the size limit, currently 1 MiB.
        Send a smaller body.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: payload_too_large
              message: Payload Too Large
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    UnsupportedMediaType:
      description: >-
        The body’s media type cannot be read. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `unsupported_media_type`: The `Content-Type` header is not a media
        type. Send `Content-Type: application/json`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: unsupported_media_type
              message: Unsupported Media Type
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    UnprocessableContent:
      description: >-
        The request cannot be used as sent. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `validation_error`: The request does not match the operation’s schema,
        a field names something that does not exist, or a value cannot be used,
        such as an id that is not a UUID, a date outside the years 0001–9999 in
        a filter, or an edited cursor. See `details`. Fix the request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: validation_error
              message: Unprocessable Entity
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    RateLimited:
      description: >-
        Too many requests (`error.code` is `rate_limited`): the API key spent a
        rate-limit policy, or the network it calls from presented too many
        invalid keys. Wait `Retry-After` seconds before retrying; it takes
        priority over `RateLimit`.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
        RateLimit:
          $ref: '#/components/headers/RateLimit'
        RateLimit-Policy:
          $ref: '#/components/headers/RateLimitPolicy'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: rate_limited
              message: Too many requests
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    InternalServerError:
      description: >-
        The request failed on the server. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `internal_error`: Something failed on our side. Retry later; reuse a
        command’s idempotency key.

        - `response_contract_violation`: Our answer broke its own schema, so it
        was withheld. `details.committed` says whether a change was saved. If
        `committed` is true, read the state instead of resending. Quote the
        request id.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: internal_error
              message: Internal Server Error
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    ServiceUnavailable:
      description: >-
        The service is briefly unavailable. Branch on `error.code`; quote
        `error.requestId` to support.


        The codes a public operation answers with it:


        - `service_unavailable`: A create ran out of time, or the service is
        briefly unavailable. Retry later with the same idempotency key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: service_unavailable
              message: Service Unavailable
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
    Error:
      description: >-
        The request failed. Branch on `error.code`; quote `error.requestId` to
        support.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: not_found
              message: Not found
              requestId: 5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        An Enrik API key, sent as `Authorization: Bearer <key>`. A key reaches
        public operations only, and only those whose scopes it holds. A few
        parameters need a scope beyond their operation’s, which the parameter
        names. The scopes:


        - `setup:read`: Read the workspace setup and its company profile.

        - `setup:run`: Change the setup: confirm the company profile, authorize
        sponsored drafting and background company research, choose what to set
        up and complete setup.

        - `workspace:read`: Read the workspace’s own profile: its health summary
        and setup state.

        - `crm:read`: Read companies with their signals, contacts and the saved
        views over them.

        - `crm:write`: Create, update and restore companies and contacts, and
        create, update and delete saved views.

        - `crm:delete`: Delete companies and contacts.

        - `twin:read`: Read the Company Twin: structured company knowledge and
        its signals.

        - `discovery:read`: Read ICP profiles, ICP assessments, discovery
        briefs, discovery jobs, candidates and the signal library.

        - `discovery:write`: Create and change ICP profiles, discovery briefs
        and signal-definition drafts, and review discovery candidates.

        - `discovery:run`: Create, start and cancel discovery jobs, and edit a
        draft one. Uses provider budget.

        - `enrichment:read`: Read the enrichment configuration and its results,
        including a record’s enrichment, formula and custom-API cells.

        - `enrichment:run`: Launch and cancel enrichment. Spends enrichment
        credits.

        - `automation:read`: Read workflows and agents with their run history,
        including a record’s agent cells.

        - `automation:run`: Run existing workflows and agents.

        - `exports:read`: Read export jobs and the fields an export can carry.

        - `exports:run`: Create, preview, start, cancel and archive CSV exports
        of companies, contacts and candidates, and download the file. Also needs
        `crm:read`. Delivering an export to a webhook destination stays in the
        app.

        - `integrations:read`: Read connections, field mappings, CRM sync jobs
        and webhook destinations.

        - `webhooks:read`: Read webhook subscriptions, the event types they can
        name and their delivery log.

        - `webhooks:write`: Subscribe a receiver URL to webhook events; edit,
        test, pause, resume and archive a subscription and rotate its signing
        secret; redeliver an event. Only workspace owners and admins can grant
        it.

        - `reporting:read`: Read analytics and dashboards.

        - `assistant:read`: Read the Assistant: its threads, messages and
        pending approvals.

        - `assistant:run`: Converse with the Assistant. Uses the workspace’s AI
        quota.

        - `assistant:write`: Approve or reject the changes the Assistant
        proposes.

````

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