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

# Create a job posting signal

> A standing search over public job postings: who is hiring for X, who is adopting technology Y, which companies are building a Z team. Hiring is the earliest public evidence of a budget being spent.

Two ways to call it. **Described**: pass `description` alone, your own sentence or paragraph about what to catch and why it matters, and an AI drafts the search net, the use-cases and the judge prompts. The response carries the drafter's `notes`, its assumptions and what it could not resolve; read them, because a signal drafted on a wrong assumption searches for the wrong thing quietly. Costs one AI call. **Explicit**: pass `kind` and `filters`, the provider's own search block as an object. An unknown filter key is a 422 listing the valid ones, never a silently dropped field.

The kinds: `technology` needs one of job_technology_slug_or (in job_filters), job_description_contains_or, tech_filters.technology_slug_or or tech_filters.technology_category_slug_or; `hiring_role` needs persona_ids or one of job_title_or, job_title_pattern_or, job_description_contains_or in job_filters; `use_case_analysis` needs use_cases and at least one company or job filter to bound the search.

Cost when it runs: per posting judged.

**Creating a signal starts nothing and bills nothing.** A signal runs only when a lead generation program picks it: [Start a lead generation run](/api-reference/signals/start-lead-generation-run) sweeps it now and records a program you can put on a schedule under Settings > Signals > Lead generation. [List signals](/api-reference/signals/list-signals) reports `used_by_program_count` per signal; zero means it is defined and never runs. List first, so you do not create a second signal over a question you already ask: duplicates bill twice and split the leads across two names.



## OpenAPI

````yaml /reference/openapi.yaml post /v2/job-posting-signals
openapi: 3.1.0
info:
  title: Tamtam Public API
  version: 2.0.0
servers:
  - url: https://api.tamtam.ai/api
security: []
paths:
  /v2/job-posting-signals:
    post:
      tags:
        - Signals
      summary: Create a job posting signal
      description: >-
        A standing search over public job postings: who is hiring for X, who is
        adopting technology Y, which companies are building a Z team. Hiring is
        the earliest public evidence of a budget being spent.


        Two ways to call it. **Described**: pass `description` alone, your own
        sentence or paragraph about what to catch and why it matters, and an AI
        drafts the search net, the use-cases and the judge prompts. The response
        carries the drafter's `notes`, its assumptions and what it could not
        resolve; read them, because a signal drafted on a wrong assumption
        searches for the wrong thing quietly. Costs one AI call. **Explicit**:
        pass `kind` and `filters`, the provider's own search block as an object.
        An unknown filter key is a 422 listing the valid ones, never a silently
        dropped field.


        The kinds: `technology` needs one of job_technology_slug_or (in
        job_filters), job_description_contains_or,
        tech_filters.technology_slug_or or
        tech_filters.technology_category_slug_or; `hiring_role` needs
        persona_ids or one of job_title_or, job_title_pattern_or,
        job_description_contains_or in job_filters; `use_case_analysis` needs
        use_cases and at least one company or job filter to bound the search.


        Cost when it runs: per posting judged.


        **Creating a signal starts nothing and bills nothing.** A signal runs
        only when a lead generation program picks it: [Start a lead generation
        run](/api-reference/signals/start-lead-generation-run) sweeps it now and
        records a program you can put on a schedule under Settings > Signals >
        Lead generation. [List signals](/api-reference/signals/list-signals)
        reports `used_by_program_count` per signal; zero means it is defined and
        never runs. List first, so you do not create a second signal over a
        question you already ask: duplicates bill twice and split the leads
        across two names.
      operationId: create-job-posting-signal
      parameters:
        - description: >-
            Target account UUID. Required for staff callers; ignored for
            customer API keys.
          explode: false
          in: query
          name: account_id
          schema:
            description: >-
              Target account UUID. Required for staff callers; ignored for
              customer API keys.
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JobPostingSignalBody'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobPostingSignalCreatedDto'
          description: OK
        default:
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ErrorModel'
          description: Error
      security:
        - apikeyAuth: []
        - bearerAuth: []
components:
  schemas:
    JobPostingSignalBody:
      additionalProperties: false
      properties:
        description:
          description: >-
            DESCRIBED path: your own sentence or paragraph about what the signal
            should catch, with context on why it matters. An AI drafts the whole
            definition from it, and the response carries its notes. Pass this
            alone, or kind and filters instead.
          type: string
        filters:
          description: >-
            EXPLICIT path: the provider's search block as an object: company
            facets at the top level (company_country_code_or, industry_id_or,
            min_employee_count_or_null, ...), plus nested job_filters
            (job_title_or, job_title_pattern_or, job_country_code_or,
            job_description_contains_or, ...) and tech_filters
            (technology_slug_or, technology_category_slug_or, ...). An unknown
            key is a 422 listing the valid ones, never a silently dropped
            filter.
        is_enabled:
          description: Defaults to true.
          type: boolean
        kind:
          description: >-
            EXPLICIT path: immutable once created, it decides which filters the
            signal may carry. technology catches adoption; hiring_role catches a
            role being hired; use_case_analysis has an AI read each posting
            against use_cases.
          enum:
            - technology
            - hiring_role
            - use_case_analysis
          type: string
        max_postings_analyzed:
          description: >-
            use_case_analysis only: how many postings per company the AI reads.
            Defaults to 10.
          format: int32
          maximum: 50
          minimum: 1
          type: integer
        name:
          description: >-
            Label for the signal, unique in the account. Optional on the
            described path (the drafter names it); required on the explicit
            path.
          type: string
        persona_ids:
          description: >-
            hiring_role only, at most 20. Referenced rather than copied, so
            editing a persona changes what the signal matches.
          items:
            type: string
          maxItems: 20
          type:
            - array
            - 'null'
        use_cases:
          description: >-
            use_case_analysis only, one to ten: the questions the AI answers
            over each posting.
          items:
            $ref: '#/components/schemas/JobPostingSignalUseCaseDto'
          maxItems: 10
          type:
            - array
            - 'null'
      type: object
    JobPostingSignalCreatedDto:
      additionalProperties: false
      properties:
        id:
          type: string
        is_enabled:
          type: boolean
        job_posting_kind:
          description: technology, hiring_role or use_case_analysis.
          type: string
        kind:
          description: >-
            The kind, as List signals reports it and as a lead generation run
            takes it.
          type: string
        name:
          type: string
        notes:
          description: >-
            DESCRIBED path: the drafter's assumptions and anything it could not
            resolve. Read them: a signal drafted on a wrong assumption searches
            for the wrong thing quietly. Empty on the explicit path.
          items:
            type: string
          type:
            - array
            - 'null'
        use_cases:
          description: The use-case names the definition carries.
          items:
            type: string
          type:
            - array
            - 'null'
        used_by_program_count:
          description: >-
            Always 0 on creation: a signal runs only when a lead generation
            program picks it.
          format: int64
          type: integer
      required:
        - job_posting_kind
        - use_cases
        - notes
        - kind
        - id
        - name
        - is_enabled
        - used_by_program_count
      type: object
    ErrorModel:
      additionalProperties: false
      properties:
        detail:
          description: >-
            A human-readable explanation specific to this occurrence of the
            problem.
          examples:
            - Property foo is required but is missing.
          type: string
        errors:
          description: Optional list of individual error details
          items:
            $ref: '#/components/schemas/ErrorDetail'
          type:
            - array
            - 'null'
        instance:
          description: >-
            A URI reference that identifies the specific occurrence of the
            problem.
          examples:
            - https://example.com/error-log/abc123
          format: uri
          type: string
        status:
          description: HTTP status code
          examples:
            - 400
          format: int64
          type: integer
        title:
          description: >-
            A short, human-readable summary of the problem type. This value
            should not change between occurrences of the error.
          examples:
            - Bad Request
          type: string
        type:
          default: about:blank
          description: A URI reference to human-readable documentation for the error.
          examples:
            - https://example.com/errors/example
          format: uri
          type: string
      type: object
    JobPostingSignalUseCaseDto:
      additionalProperties: false
      properties:
        name:
          description: Chip label, unique within the signal.
          minLength: 1
          type: string
        prompt:
          description: >-
            What a posting must say to fall into this use-case, and what to
            extract.
          minLength: 1
          type: string
      required:
        - name
        - prompt
      type: object
    ErrorDetail:
      additionalProperties: false
      properties:
        location:
          description: >-
            Where the error occurred, e.g. 'body.items[3].tags' or
            'path.thing-id'
          type: string
        message:
          description: Error message text
          type: string
        value:
          description: The value at the given location
      type: object
  securitySchemes:
    apikeyAuth:
      description: Account API key passed in the Authorization header
      in: header
      name: Authorization
      type: apiKey
    bearerAuth:
      description: Bearer JWT obtained via the OAuth 2.1 authorization flow
      scheme: bearer
      type: http

````