# Your first API request

Start with a validated build in your workspace. It supplies the source identifier, definition version, schema, limits, and connection instructions for that collection.

## 1. Inspect and build

Enter a public collection URL in the [API generator](/#start-source). Review the selected records and sample fields before building. Wait for a successful build, then open its saved API detail page. A preview or a build still in progress is not an accepted API.

Compare the output schema and sample records with your intended use. Check the available page and detail limits; different sources can support different inputs. The fictional [table-lamp example](/docs/choosing-a-source/) shows how to move from a collection URL through reviewed fields to an accepted contract.

## 2. Prepare your server

Copy the exact API base URL and request example supplied by your workspace. When machine access is available, create an API key and keep it in your server’s secret storage. Never embed it in browser JavaScript.

Set these values in your server environment before running the example:

| Variable | Value |
| --- | --- |
| `CLEANEDWEB_API_BASE` | Supplied HTTPS API origin, without a path. |
| `CLEANEDWEB_SOURCE_ID` | Saved source identifier. |
| `CLEANEDWEB_DEFINITION_VERSION` | Full saved 64-character lowercase definition version. |
| `CLEANEDWEB_API_KEY` | Server credential with `run` access to this API. |
| `CLEANEDWEB_IDEMPOTENCY_KEY` | Unique key saved with this intended request before sending. |

For the request key, use a UUID or 1–200 letters, numbers, `.`, `_`, `:`, or `-`. Save it alongside the source, version, and inputs. Reuse it only to recover the same request; choose a new key for a new execution. The API origin must be the one supplied with your API, not a source website URL.

## 3. Make a bounded request

For a collection API supporting these inputs, this request collects at most one page and does not request detail-page enrichment. It executes the source and may incur usage. Search APIs can require a constrained `query` instead; follow the generated request when its contract differs.

```bash
umask 077
: "${CLEANEDWEB_IDEMPOTENCY_KEY:?Set the saved key for this request}"

curl --fail-with-body --max-time 60 \
  "${CLEANEDWEB_API_BASE}/v1/sources/${CLEANEDWEB_SOURCE_ID}/run" \
  -H "Authorization: Bearer ${CLEANEDWEB_API_KEY}" \
  -H "Idempotency-Key: ${CLEANEDWEB_IDEMPOTENCY_KEY}" \
  -H 'Content-Type: application/json' \
  --data "{\"expected_version\":\"${CLEANEDWEB_DEFINITION_VERSION}\",\"input\":{\"max_pages\":1,\"detail_limit\":0}}"
```

`expected_version` requires the active source definition to match your saved version. If it has changed, inspect the new definition and schema before updating your integration. Do not remove the version check merely to get past a conflict.

## 4. Inspect the result

Read `records` together with `summary`, not on their own. A shortened, illustrative response might look like this; use the fields and version returned by your API rather than copying these values:

```json
{
  "records": [{ "name": "Arc table lamp", "price": 48 }],
  "summary": {
    "status": "bounded",
    "within_scope_passed": true,
    "catalog_complete": false
  }
}
```

The shortened example omits version and delivery fields. In the full response, require both `summary.definition_version` and `metadata.definition_version` to equal `CLEANEDWEB_DEFINITION_VERSION`. Check `summary.within_scope_passed`, `summary.status`, and the limits used. In this example, the request satisfied its selected boundary; it did not establish full-catalog coverage. A `partial` status or `within_scope_passed: false` needs review even when records were returned. See [pagination and output](/docs/pagination/) before increasing limits.

Keep `delivery.runId`, `delivery.chargeReceiptId`, and `traceId` where returned. Do not treat HTTP 200, a nonempty array, or a successful build as proof that all source records were collected. If the connection times out, keep the saved request key and follow [idempotency and recovery](/docs/idempotency/) before retrying.

## 5. Integrate carefully

Store only the data you need, validate fields before downstream use, and preserve missing values rather than inventing them. See the [Run API reference](/docs/run-api/), [authentication and limits](/docs/authentication/), and [errors and retries](/docs/errors/) before scheduling recurring runs.
