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

# List hiring signals

> Return company-level hiring events, newest first. Every filter is optional and they combine with AND; a comma-separated filter matches any of its values. Page with `cursor` until `has_more` is false.

Charged \$0.03 per signal returned (30 credits) from your wallet. No plan includes signals, and a page that returns nothing is free. See [Billing](/billing).



## OpenAPI

````yaml /openapi.yaml get /api/signals
openapi: 3.0.3
info:
  title: Jobo Enterprise API
  description: >
    Search and stream job listings, look up company profiles, geocode locations
    and read the occupation taxonomy.


    Auto Apply is coming soon. Build against the [sandbox](/sandbox) today with
    a `jbe_test_…` key, no approval needed. Live applications need Jobo to
    approve your business: request it in the dashboard under **Auto Apply →
    Getting started → Request live access**.
  version: '2026-08-31'
  contact:
    name: Jobo Support
    url: https://jobo.world
    email: support@jobo.world
  license:
    name: Proprietary — see terms of service
    url: https://jobo.world/terms
  termsOfService: https://jobo.world/terms
servers:
  - url: https://connect.jobo.world
    description: Production
security:
  - ApiKeyAuth: []
tags:
  - name: Jobs
    description: Search and retrieve job listings
  - name: Feed
    description: Bulk job feeds and expiration tracking
  - name: Companies
    description: Company profiles and company-scoped job listings
  - name: Signals
    description: Company-level hiring events detected from job postings
  - name: Auto Apply
    description: >-
      Submit job applications through Jobo: a blocking create returns the form's
      typed fields, answers are validated and filled synchronously, and the call
      returns the next step or the result.
  - name: Locations
    description: Geocoding and location services
  - name: Occupations
    description: The occupation taxonomy jobs are classified into
paths:
  /api/signals:
    get:
      tags:
        - Signals
      summary: List hiring signals
      description: >-
        Return company-level hiring events, newest first. Every filter is
        optional and they combine with AND; a comma-separated filter matches any
        of its values. Page with `cursor` until `has_more` is false.


        Charged \$0.03 per signal returned (30 credits) from your wallet. No
        plan includes signals, and a page that returns nothing is free. See
        [Billing](/billing).
      operationId: listHiringSignals
      parameters:
        - name: types
          in: query
          schema:
            type: string
          description: >-
            Comma-separated signal types, for example
            `hiring_surge,new_country`. See [signal
            types](/guides/hiring-signals#signal-types). An unknown type returns
            `400`.
        - name: company_ids
          in: query
          schema:
            type: string
          description: Comma-separated company IDs (at most 100).
        - name: domains
          in: query
          schema:
            type: string
          description: >-
            Comma-separated company website domains, for example `stripe.com`
            (at most 100).
        - name: detected_after
          in: query
          schema:
            type: string
            format: date
          description: Earliest detection day, inclusive (`yyyy-MM-dd`).
        - name: detected_before
          in: query
          schema:
            type: string
            format: date
          description: Latest detection day, inclusive (`yyyy-MM-dd`).
        - name: created_after
          in: query
          schema:
            type: string
            format: date-time
          description: >-
            Only signals first stored after this instant, for example
            `2026-11-12T09:30:00Z`. To poll for new signals, pass the newest
            `created_at` you have seen.
        - name: countries
          in: query
          schema:
            type: string
          description: Comma-separated ISO country codes of the company's headquarters.
        - name: company_sizes
          in: query
          schema:
            type: string
          description: Comma-separated company size bands, as returned in `company.size`.
        - name: industries
          in: query
          schema:
            type: string
          description: >-
            Comma-separated industries, matched against the company's primary
            industry and its industry list.
        - name: categories
          in: query
          schema:
            type: string
          description: >-
            Comma-separated company categories, as returned in
            `company.categories`.
        - name: min_strength
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          description: Only signals with at least this strength.
        - name: exclude_agencies
          in: query
          schema:
            type: boolean
            default: false
          description: Leave out staffing agencies.
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
            minimum: 1
            maximum: 200
          description: Signals per page.
        - name: cursor
          in: query
          schema:
            type: string
          description: >-
            The previous page's `next_cursor`. Keep every filter unchanged
            between pages.
      responses:
        '200':
          description: One page of signals, newest first
          headers:
            X-Credits-Deducted:
              schema:
                type: integer
              description: >-
                Credits charged to the wallet for this response, 30 per signal.
                Absent on an empty page.
            X-Credits-Balance:
              schema:
                type: integer
              description: >-
                Your wallet balance in credits after the charge. Omitted when
                nothing was charged.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HiringSignalListResponse'
        '400':
          description: Invalid filter, date, limit or cursor
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/ServerError'
      x-codeSamples:
        - lang: cURL
          source: |
            curl -G "https://connect.jobo.world/api/signals" \
              -H "X-Api-Key: $JOBO_API_KEY" \
              --data-urlencode "types=hiring_surge,new_country" \
              --data-urlencode "min_strength=70" \
              --data-urlencode "exclude_agencies=true"
components:
  schemas:
    HiringSignalListResponse:
      type: object
      required:
        - signals
        - has_more
      properties:
        signals:
          type: array
          items:
            $ref: '#/components/schemas/HiringSignal'
        next_cursor:
          type: string
          description: Pass as `cursor` to read the next page. Absent on the last page.
        has_more:
          type: boolean
    ProblemDetails:
      type: object
      description: >-
        RFC 7807 problem details, returned by endpoint errors as
        `application/problem+json`. See [Errors](/errors) for every envelope and
        stable code.
      properties:
        type:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        status:
          type: integer
          nullable: true
        detail:
          type: string
          nullable: true
        instance:
          type: string
          nullable: true
        code:
          type: string
          nullable: true
          description: >-
            Stable machine-readable error code, such as `invalid_request`,
            `invalid_cursor`, `feed_changed`, `not_available_in_sandbox` or an
            Auto Apply code. Branch on this rather than on `title` or `detail`.
            See [stable error codes](/errors#stable-error-codes).
        docs_url:
          type: string
          format: uri
          description: >-
            Documentation page for the error. Sent with `code` on `400`, `409`,
            `413`, `415` and `422` responses to requests made with a customer
            API key.
          example: https://jobo.world/docs/guides/sync-a-database
        api_version:
          $ref: '#/components/schemas/AutoApplyApiVersion'
    HiringSignal:
      type: object
      description: A company-level hiring event derived from the company's job postings.
      properties:
        id:
          type: string
          format: uuid
        type:
          type: string
          description: >-
            The signal type, for example `hiring_surge`. More types may be
            added, so ignore a value you do not know. See [signal
            types](/guides/hiring-signals#signal-types).
        detected_on:
          type: string
          format: date
          description: The UTC day the signal was detected for.
        created_at:
          type: string
          format: date-time
          description: >-
            When the signal was first stored. It does not change when the signal
            is detected again.
        window_start:
          type: string
          format: date
          description: First day of the period the signal describes.
        window_end:
          type: string
          format: date
          description: Last day of the period the signal describes.
        strength:
          type: integer
          minimum: 1
          maximum: 100
          description: Comparable between signals of the same type.
        company:
          $ref: '#/components/schemas/HiringSignalCompany'
        details:
          type: object
          additionalProperties: true
          description: >-
            Facts specific to the type, for example `new_jobs`,
            `baseline_weekly_avg` and `ratio` for a surge, or `country` for a
            new country. Always carries `is_agency`.
        evidence_job_ids:
          type: array
          items:
            type: string
            format: uuid
          description: >-
            Up to five job IDs behind the signal. Read them with `GET
            /api/jobs/{id}`.
    AutoApplyApiVersion:
      type: string
      description: Version of the Auto Apply API contract.
      enum:
        - '2026-08-31'
      example: '2026-08-31'
    ApiAuthError:
      type: object
      description: >-
        Body of a gateway `401`. Plain JSON, not `problem+json`. Match on the
        status; `error` is a sentence that may be reworded.
      required:
        - error
      properties:
        error:
          type: string
          example: Invalid or expired API key
        api_version:
          $ref: '#/components/schemas/AutoApplyApiVersion'
    InsufficientCreditsError:
      type: object
      description: >-
        Body of a `402`. Plain JSON, not `problem+json`. The `error` value
        `Insufficient credits` is a stable match key; the `detail` sentence may
        be reworded at any time.
      required:
        - error
        - detail
        - group
        - credits_required
        - credits_balance
        - cost_per_request_usd
      properties:
        error:
          type: string
          enum:
            - Insufficient credits
        detail:
          type: string
          example: >-
            This request needs 75 credits ($0.075). Your wallet balance is 12
            credits ($0.012). Top up your wallet to continue.
        group:
          type: string
          description: The [rate-limit group](/rate-limits) the request is priced under.
          example: JobSearch
        credits_required:
          type: integer
          format: int64
          description: Credits the request needs beyond your remaining included jobs.
        credits_balance:
          type: integer
          format: int64
          description: Your wallet balance in credits.
        quota_remaining:
          type: integer
          format: int64
          nullable: true
          description: >-
            Included jobs remaining. Sent on per-job endpoints (search, feed,
            company jobs); null when no Job Search plan applies.
        cost_per_request_usd:
          type: number
          format: double
          description: '`credits_required` in US dollars.'
          example: 0.075
        upgrade_url:
          type: string
          format: uri
          nullable: true
          description: >-
            Opens checkout for `recommended_plan` on the credits page. Null when
            a top-up is the way to continue, as for geocoding and Company
            Enrichment.
          example: >-
            https://enterprise.jobo.world/credits?plan=job_search&tier=2&src=api_402
        top_up_url:
          type: string
          format: uri
          nullable: true
          description: >-
            Opens a wallet top-up on the credits page, preset to cover the
            shortfall.
          example: https://enterprise.jobo.world/credits?topup=10&src=api_402
        recommended_plan:
          type: object
          allOf:
            - $ref: '#/components/schemas/RecommendedPlan'
          nullable: true
          description: >-
            The plan that would include this usage, priced for your account.
            Null whenever `upgrade_url` is null.
    ApiRateLimitError:
      type: object
      description: >
        Body of a gateway `429`. Plain JSON, not `problem+json`. When a
        rate-limit window is exhausted, `code` is `rate_limit_exceeded` and
        `group` names the exhausted [rate-limit group](/rate-limits); the Auto
        Apply groups add `api_version`. The `429` for [repeated authentication
        failures](/rate-limits#repeated-authentication-failures) has neither
        `code` nor `group`. `retry_after_seconds` matches the `Retry-After`
        header.
      required:
        - error
        - detail
        - retry_after_seconds
      properties:
        code:
          type: string
          enum:
            - rate_limit_exceeded
        error:
          type: string
          example: Rate limit exceeded
        detail:
          type: string
          example: >-
            Per-minute JobSearch request limit of 180 exceeded. Try again
            shortly.
        group:
          type: string
          example: JobSearch
        retry_after_seconds:
          type: integer
          minimum: 0
          nullable: true
        api_version:
          $ref: '#/components/schemas/AutoApplyApiVersion'
        upgrade_url:
          type: string
          format: uri
          nullable: true
          description: >-
            Sent only without a subscription, outside the Auto Apply groups.
            Opens checkout for `recommended_plan`, which raises your limits.
          example: >-
            https://enterprise.jobo.world/credits?plan=job_search&tier=1&src=api_429
        top_up_url:
          type: string
          format: uri
          nullable: true
          description: >-
            Always null on a `429`, because a wallet top-up does not raise rate
            limits. Sent alongside `upgrade_url`.
        recommended_plan:
          type: object
          allOf:
            - $ref: '#/components/schemas/RecommendedPlan'
          nullable: true
          description: Sent alongside `upgrade_url`. The plan it opens.
    UnhandledError:
      type: object
      description: >-
        Body of an unexpected `500`, or of a `503` after a transient database
        conflict. Plain JSON, not `problem+json`.
      required:
        - message
        - detail
      properties:
        message:
          type: string
          example: An error occurred
        detail:
          type: string
          nullable: true
          description: Null in production. Never depend on it.
    HiringSignalCompany:
      type: object
      description: The company a signal is about, as it was when the signal fired.
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          nullable: true
        domain:
          type: string
          nullable: true
          description: Website host without `www.`.
        country_code:
          type: string
          nullable: true
        size:
          type: string
          nullable: true
        industry:
          type: string
          nullable: true
          description: Primary industry.
        industries:
          type: array
          items:
            type: string
        categories:
          type: array
          items:
            type: string
        is_agency:
          type: boolean
          description: Staffing agency. Its postings are its clients' hiring.
    RecommendedPlan:
      type: object
      description: >-
        A plan offered on a `402` or `429`. Open `upgrade_url` from the same
        body to subscribe.
      required:
        - package_type
        - tier
        - name
        - monthly_price_usd
        - included_jobs_per_month
      properties:
        package_type:
          type: string
          enum:
            - job_search
            - jobs_feed
          description: >-
            `job_search` for a Job Search plan; `jobs_feed` for the Unlimited
            plan.
        tier:
          type: integer
          minimum: 0
          maximum: 3
          nullable: true
          description: >-
            Job Search tier: 0 Lite, 1 Starter, 2 Growth, 3 Scale. Null for
            Unlimited.
          example: 2
        name:
          type: string
          example: Job Search — Growth
        monthly_price_usd:
          type: number
          format: double
          description: Monthly price in US dollars for your account.
          example: 199
        included_jobs_per_month:
          type: integer
          format: int64
          nullable: true
          description: >-
            Jobs included each month, shared across Search, Feed, Export, and
            Outbound. Null for Unlimited, which has no per-job charge on Feed,
            Export, and Outbound.
          example: 500000
  responses:
    Unauthorized:
      description: >-
        Missing, invalid or expired API key. The body is plain JSON whose
        `error` is `Missing X-Api-Key header` or `Invalid or expired API key`.
        See [Errors](/errors#401-unauthorized).
      headers:
        WWW-Authenticate:
          description: Always `ApiKey realm="api.jobo.world"`.
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiAuthError'
    PaymentRequired:
      description: >
        Your remaining included jobs plus your wallet balance cannot cover this
        request, so it returns no jobs. Jobo checks the worst case (a full page
        or batch) before the request runs; see [Billing](/billing#request-flow).
        Open `top_up_url` to top up your wallet, or `upgrade_url` to subscribe
        to the plan in `recommended_plan`.


        Match on the stable `error` value `"Insufficient credits"`; the `detail`
        sentence can change. Credits are the wallet's wire unit: 1,000 credits =
        $1.00. The full body is on [Errors](/errors#402-payment-required).
      headers:
        X-Credits-Required:
          description: Credits the request needs beyond your remaining included jobs.
          schema:
            type: integer
            format: int64
        X-Credits-Balance:
          description: Your current wallet balance in credits.
          schema:
            type: integer
            format: int64
        X-Quota-Remaining:
          description: Included jobs remaining, when a Job Search plan applies.
          schema:
            type: integer
            format: int64
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/InsufficientCreditsError'
    TooManyRequests:
      description: >-
        Rate limit exceeded. Nothing is charged. Wait at least `Retry-After`
        seconds before you retry. See [Rate
        limits](/rate-limits#when-you-exceed-a-limit).
      headers:
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
            minimum: 0
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiRateLimitError'
    ServerError:
      description: >-
        Unexpected server error. Back off and retry. See [Unhandled
        errors](/errors#unhandled-errors).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/UnhandledError'
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-Api-Key
      description: >-
        Your Jobo API key. Create one in the
        [dashboard](https://enterprise.jobo.world/api-keys?src=docs) under
        **Developers → API Keys**. Live keys start with `jbe_live_` and sandbox
        keys with `jbe_test_`.

````

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