Business Endpoints

Both business operations are part of All tools. A start needs the relevant scope and enough credits, and the tool must be available in /v1/health. Free credits also follow the free limits. Accepted starts return 202 Accepted.

Both endpoints are preview. Preview means the contract may still evolve before stable release; returned data is live business data, not sample output.

POST/v1/business/search

Searches for local business listings by query, category, or both.

Required Access

  • Access: Paid plans that include this family, or free credits (guest trial or verified account) within the free limits.
  • Operation family: Business data
  • Scope: api:business:read
  • Credits: 8 credits reserved on acceptance
  • Idempotency: Idempotency-Key header required

Request

curl -X POST https://www.chab.ai/v1/business/search \
  -H "Authorization: Bearer CHAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: business-search-001" \
  -d '{"query":"coffee shops","category":"cafe","engine":"google","location":{"country":"US","region":"TX","city":"Austin"},"language":"en-US","limit":10}'

Area search:

{
  "query": "coffee shops",
  "category": "cafe",
  "engine": "google",
  "location": {
    "country": "US",
    "region": "TX",
    "city": "Austin"
  },
  "language": "en-US",
  "limit": 10
}

Radius search:

{
  "category": "coffee",
  "engine": "google",
  "location": {
    "country": "US",
    "latitude": 30.2672,
    "longitude": -97.7431,
    "radius_km": 2.5
  },
  "language": "en-US",
  "limit": 10
}

Fields:

  • query: optional string, 1 to 200 characters.
  • category: optional string, 1 to 80 characters.
  • At least one of query or category is required. When both are present, Chab uses both to narrow the search.
  • engine: required. google is the supported engine.
  • location.country: required ISO 3166-1 alpha-2 country code.
  • Area location: optional region, city, and postal_code. city searches that city: local and English names both work (Lisboa or Lisbon), and a city Chab cannot find in the country is rejected with validation_failed instead of searching the whole country. The result names the place searched in location.resolved_name, such as Rotterdam, South Holland, Netherlands. When several places share the name, add region (for example OR for Portland, Oregon); without it Chab searches the biggest one and says so in a warning.
  • Radius location: country, latitude, longitude, and radius_km are required together. radius_km accepts 0.1 to 25.
  • Area and radius fields cannot be mixed in one request.
  • language: required BCP 47 language tag, such as en-US, en-GB, or de-DE.
  • limit: optional integer from 1 to 20; defaults to 10.
  • callback_url, callback_secret, callback_events, and callback_notify_on_expiration: optional one-off operation callback fields. They are available only for paid-funded starts; starts on free credits must omit callback fields and poll the operation URLs instead. Free credits are one-off grants and do not refresh monthly.

Unknown request fields are rejected. If a requested region or postal code cannot be narrowed precisely but the country is supported, the operation can still succeed with a structured warning.

Async Response

{
  "operation": {
    "id": "op_01JZ7H0A1B2C3D4E5F6G7H8J9K",
    "status": "queued",
    "operation_key": "business.search",
    "family": "business",
    "status_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K",
    "result_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K/result",
    "estimated_credits": 8,
    "result_available": false,
    "warnings": []
  },
  "meta": {
    "request_id": "req_123",
    "credits": {
      "estimated": 8,
      "reserved": 8,
      "currency": "credit"
    }
  }
}

Succeeded Status

GET /v1/operations/{id} returns the operation status. Business operations are asynchronous Chab operations; there is no public provider task handle.

Result

GET /v1/operations/{id}/result returns retained business results after success:

{
  "data": {
    "result": {
      "engine": "google",
      "location": {
        "country": "US",
        "region": "TX",
        "city": "Austin"
      },
      "language": "en-US",
      "query": "coffee shops",
      "category": "cafe",
      "fetched_at": "2026-06-29T12:00:05+00:00",
      "result_count": 1,
      "complete": true,
      "businesses": [
        {
          "name": "Capital Coffee Lab",
          "address": "100 Congress Ave, Austin, TX 78701",
          "geo": {
            "latitude": 30.2635,
            "longitude": -97.7431
          },
          "website": "https://example.com",
          "phone": "+1 512-555-0100",
          "rating": 4.7,
          "review_count": 128,
          "category": "Coffee shop",
          "source_category": "Coffee shop",
          "hours": {
            "raw": {
              "monday": "07:00-18:00"
            }
          },
          "status": "open",
          "business_ref": "bref_...",
          "duplicate_group": null,
          "confidence": {
            "score": 1,
            "availability": "available",
            "source": "chab"
          },
          "observed_at": "2026-06-20T00:00:00+00:00",
          "fetched_at": "2026-06-29T12:00:05+00:00",
          "availability": {
            "name": "available",
            "address": "available",
            "phone": "available"
          },
          "warnings": []
        }
      ]
    },
    "artifacts": [],
    "warnings": [],
    "result_expires_at": "2026-07-02T12:00:05+00:00"
  },
  "meta": {
    "request_id": "req_123"
  }
}

Business rows are sparse-safe:

  • Missing fields are returned as null with an explicit availability entry and, where useful, a field_unavailable warning.
  • Older observed records can include a stale_data warning.
  • Possible duplicate listings are not merged. Each duplicate candidate keeps its own row, shares a duplicate_group, and includes a duplicate_candidate warning.
  • business_ref is an opaque Chab reference. Use it with POST /v1/business/details while the source result is still retained.

POST/v1/business/details

Retrieves one business profile from a prior business_ref, or from a fallback identity object.

Required Access

  • Access: Pro or Scale, or free credits (guest trial or verified account) within the free limits.
  • Operation family: Business data
  • Scope: api:business:read
  • Credits: 4 credits reserved on acceptance. Free credits are one-off grants and do not refresh monthly.
  • Idempotency: Idempotency-Key header required

Request

curl -X POST https://www.chab.ai/v1/business/details \
  -H "Authorization: Bearer CHAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: business-details-001" \
  -d '{"engine":"google","language":"en-US","business_ref":"bref_EXAMPLE"}'

Lookup by reference:

{
  "engine": "google",
  "language": "en-US",
  "business_ref": "bref_..."
}

Fallback identity lookup:

{
  "engine": "google",
  "language": "en-US",
  "identity": {
    "name": "Capital Coffee Lab",
    "address": "100 Congress Ave, Austin, TX 78701",
    "location": {
      "country": "US",
      "region": "TX",
      "city": "Austin"
    }
  }
}

Fields:

  • Provide exactly one of business_ref or identity.
  • business_ref: opaque reference returned by business search or details. It expires when the source operation result expires.
  • identity.name: required with identity, 1 to 200 characters.
  • identity.address: required with identity, 1 to 300 characters.
  • identity.location: same area-or-radius shape as business search.
  • Search-only fields such as query, category, and limit are rejected.
  • callback_url, callback_secret, callback_events, and callback_notify_on_expiration: optional one-off operation callback fields for paid-funded starts only. Starts on free credits must omit callback fields and poll the operation URLs instead.

Async Response

The create response has the same operation envelope shape as business search, with operation_key: "business.details" and a 4 credit estimate/reservation.

Result

{
  "data": {
    "result": {
      "engine": "google",
      "language": "en-US",
      "lookup": {
        "mode": "ref"
      },
      "fetched_at": "2026-06-29T12:00:05+00:00",
      "complete": true,
      "business": {
        "name": "Capital Coffee Lab",
        "address": "100 Congress Ave, Austin, TX 78701",
        "business_ref": "bref_...",
        "confidence": {
          "score": 1,
          "availability": "available",
          "source": "chab"
        },
        "availability": {},
        "warnings": []
      }
    },
    "artifacts": [],
    "warnings": [],
    "result_expires_at": "2026-07-02T12:00:05+00:00"
  },
  "meta": {
    "request_id": "req_123"
  }
}

When no matching business is available, the operation can still succeed with business: null, complete: false, and a field_unavailable warning.

Error Handling

Common errors include:

  • validation_failed: malformed request body, unsupported location or language, mixed location shapes, missing query/category, missing or multiple lookup modes, or an invalid, expired, tampered, cross-team, or unavailable business_ref.
  • operation_family_not_included: the team plan does not include business data operations.
  • provider_unavailable, provider_error, provider_response_invalid, or provider_temporarily_rate_limited: provider data was unavailable or temporarily limited. These errors use the standard operation error envelope and never expose raw provider identifiers.