---
title: Workflows and data stack
url: https://docs.schemalabs.ai/integrations/data-stack
description: Call Schema from any HTTP node, schedule syncs and refreshes from your orchestrator, and land bundles in the warehouse.
---

# Workflows and data stack

> Call Schema from any HTTP node, schedule syncs and refreshes from your orchestrator, and land bundles in the warehouse.

Any tool with an HTTP Request node can call Schema, and any orchestrator can keep an endpoint current. The contract is the same everywhere: `POST /v2/run` for a stateless quick run, `POST /v2/serve/{endpoint_id}` for a live endpoint, a bearer key, JSON in, the bundle out.

## Workflow and no-code tools

| Setting | Value |
|---|---|
| Method | `POST` |
| URL | `https://api.schemalabs.ai/v2/serve/{endpoint_id}` (or `/v2/run`) |
| Headers | `Authorization: Bearer {{ $secrets.SCHEMA_API_KEY }}`, `Content-Type: application/json` |
| Body | `{ "tables": [ { "id": "...", "columns": [...], "rows": [...] } ] }` |

Map the incoming item (a form submission, a CRM row, a CSV chunk) into `rows`. Use a `serve`-scoped key for the serve call; the sync, refresh, and job-polling steps below need `manage` and `read`. Then branch on the bundle:

- `prediction.results[0].confidence` above your threshold → automate; below → human review.
- `tables[0].column_profile[*].pii == true` → mask before the next step.
- `cross_table_map.entity_matches[*].confidence` in your review band → review queue.
- `imputation.filled[*]` non-empty → write filled values back with their row confidence.

Endpoint creation, refresh, and batch runs return `202` with a `job_id`. Add a wait-and-poll loop on `GET /v2/jobs/{job_id}` (2 s, 4 s, 8 s, then every 15 s) and continue on `status == "done"`. Every failure is one JSON envelope with `error.type`; branch on it, and honor `Retry-After` on `429`. See [Errors](https://docs.schemalabs.ai/api-reference#errors).

## Keep the layer current

A DAG or workflow that runs after each load:

```text
 load source  →  POST /v2/data/:id/sync  →  POST /v2/endpoints/:id/refresh
                                         →  poll job  →  read report
```

Refresh bills only added and changed rows and re-scores held-out; a new report is minted per run so drift is visible in the trail. Use an `Idempotency-Key` per scheduled run so retries never duplicate work.

## Land the bundle in the warehouse

For large tables, run in batch and write the output to a warehouse table:

```http
POST /v2/run
{ "data": ["snowflake://example/warehouse/events_2025"],
  "target": { "column": "converted" },
  "options": { "processing": "batch", "out": "warehouse://schema.outputs" } }
```

The bundle (per-table profile, imputation, predictions, unified rows) lands as rows you can join and model on. Batch bills the batch rate. See [Batch and large runs](https://docs.schemalabs.ai/data#batch-and-large-runs).

## dbt

Model the bundle tables like any source: `unified_rows` becomes a golden-record model, `imputation.filled` a repair log, `prediction.results` a scored table with the endpoint's `report_id` as lineage.

## Metering

Sync itself is free; the pass after it bills only the diff. See [Usage and billing](https://docs.schemalabs.ai/billing).

## Other channels

Wherever Schema is consumed outside the direct API (cloud model catalogs, warehouse model pages, orchestration and agent layers), the contract is the same REST API, the same output bundle, and the same meter. For a channel you need, [contact us](https://docs.schemalabs.ai/support).
