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

# Test the API

> Use a new `test` datasource to upload sample `purchase_order` JSONs.

<Steps>
  <Step title="Create the test datasource">
    Open **Admin → Connectors → Custom Source**. Create a new datasource named `test` with document types `purchase_order`. Save its client ID, fingerprint, and private key.
  </Step>

  <Step title="Get a token">
    Follow [Quickstart](/quickstart) using the `test` datasource's credentials and `CLIENT_ID = "<tenant_slug>/test"`. Copy the returned token into your shell:

    ```sh theme={null}
    export TOKEN='<access_token>'
    export BASE_URL='https://app.teampascal.com/api/v1/custom-source'
    ```
  </Step>

  <Step title="Open a dry-run upload">
    ```sh theme={null}
    UPLOAD_ID=$(curl --fail-with-body -sS "$BASE_URL/uploads" \
      -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
      -d '{"datasource":"test","mode":"incremental","dry_run":true}' | jq -r '.upload_id')
    ```
  </Step>

  <Step title="Send ten sample purchase orders">
    Save this as `records.json`:

    ```json theme={null}
    {"records": [
      {"id": "1001", "doc_type": "purchase_order", "data": {"PONumber": "PO-88201", "Customer": "Example Foods", "OrderDate": "2026-09-01", "Lines": [{"SKU": "SKU-100", "Qty": 1}]}},
      {"id": "1002", "doc_type": "purchase_order", "data": {"PONumber": "PO-88202", "Customer": "Example Foods", "OrderDate": "2026-09-01", "Lines": [{"SKU": "SKU-100", "Qty": 1}]}},
      {"id": "1003", "doc_type": "purchase_order", "data": {"PONumber": "PO-88203", "Customer": "Example Foods", "OrderDate": "2026-09-01", "Lines": [{"SKU": "SKU-100", "Qty": 1}]}},
      {"id": "1004", "doc_type": "purchase_order", "data": {"PONumber": "PO-88204", "Customer": "Example Foods", "OrderDate": "2026-09-01", "Lines": [{"SKU": "SKU-100", "Qty": 1}]}},
      {"id": "1005", "doc_type": "purchase_order", "data": {"PONumber": "PO-88205", "Customer": "Example Foods", "OrderDate": "2026-09-01", "Lines": [{"SKU": "SKU-100", "Qty": 1}]}},
      {"id": "1006", "doc_type": "purchase_order", "data": {"PONumber": "PO-88206", "Customer": "Example Foods", "OrderDate": "2026-09-01", "Lines": [{"SKU": "SKU-100", "Qty": 1}]}},
      {"id": "1007", "doc_type": "purchase_order", "data": {"PONumber": "PO-88207", "Customer": "Example Foods", "OrderDate": "2026-09-01", "Lines": [{"SKU": "SKU-100", "Qty": 1}]}},
      {"id": "1008", "doc_type": "purchase_order", "data": {"PONumber": "PO-88208", "Customer": "Example Foods", "OrderDate": "2026-09-01", "Lines": [{"SKU": "SKU-100", "Qty": 1}]}},
      {"id": "1009", "doc_type": "purchase_order", "data": {"PONumber": "PO-88209", "Customer": "Example Foods", "OrderDate": "2026-09-01", "Lines": [{"SKU": "SKU-100", "Qty": 1}]}},
      {"id": "1010", "doc_type": "purchase_order", "data": {"PONumber": "PO-88210", "Customer": "Example Foods", "OrderDate": "2026-09-01", "Lines": [{"SKU": "SKU-100", "Qty": 1}]}}
    ]}
    ```

    ```sh theme={null}
    curl --fail-with-body -sS -X PUT "$BASE_URL/uploads/$UPLOAD_ID/records" \
      -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
      --data-binary @records.json
    ```

    The response has `accepted: 10` and `record_count: 10`.
  </Step>

  <Step title="Send one more">
    ```sh theme={null}
    curl --fail-with-body -sS -X PUT "$BASE_URL/uploads/$UPLOAD_ID/records" \
      -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
      -d '{"records":[{"id":"1011","doc_type":"purchase_order","data":{"PONumber":"PO-88211","Customer":"Example Foods","OrderDate":"2026-09-01","Lines":[{"SKU":"SKU-100","Qty":1}]}}]}'
    ```

    The response has `accepted: 1` and `record_count: 11`.
  </Step>

  <Step title="Close the upload">
    ```sh theme={null}
    curl --fail-with-body -sS -X POST "$BASE_URL/uploads/$UPLOAD_ID/close" \
      -H "Authorization: Bearer $TOKEN"
    ```

    The response has `status: "done"`.
  </Step>

  <Step title="Read the report">
    ```sh theme={null}
    curl --fail-with-body -sS "$BASE_URL/uploads/$UPLOAD_ID" \
      -H "Authorization: Bearer $TOKEN" \
      | jq '{status, dry_run, record_count, merged_counts, report: {status: .report.status, errors: .report.errors}}'
    ```

    Expected output:

    ```json theme={null}
    {
      "status": "done",
      "dry_run": true,
      "record_count": 11,
      "merged_counts": null,
      "report": {"status": "passed", "errors": []}
    }
    ```

    If close returned `status: "rejected"`, drop the report projection from the `jq` filter and read `report.per_type[].errors` for the finding to fix; top-level `report.errors` is empty on both outcomes.

    `report.per_type` carries per-document-type warnings such as a missing SKU map. The dry run leaves documents unchanged.
  </Step>
</Steps>
