Echo/Docs

CLI command

export

Warehouse exports: Echo's events and records loaded into your own BigQuery tables on a schedule, incrementally, with a load report for every run.

Invocation#

Shell
echo-cli export list
echo-cli export create --source <table> --project <project> --dataset <dataset> --table <table> --every-hours <hours> --by <name>
echo-cli export run <export-id>
echo-cli export runs <export-id>
echo-cli export remove <export-id>

Inputs and output#

list writes { exports, sources }: every export (id, source, project_id, dataset_id, table_id, every_hours, exported_through, created_by, created_at, latest_run) and the Echo tables an export may load — web_analytics_events, mobile_analytics_events, automation_audit and integration_failures. create writes the export; remove writes the export it removed with its reports. run and runs write load reports (id, export_id, started_at, from_time, through_time, source_rows, loaded_rows, outcome running, done or failed, finished_at, error), runs newest first.

State effect#

Every verb calls Echo Web's authenticated /api/warehouse/exports or /api/warehouse/runs with ECHO_INTERNAL_BEARER at ECHO_WEB_BASE_URL; the Warehouse screen and the Warehouse export section of Echo Desktop's GEO screen call the same operations, and echo-mcp reads exports and reports (echo_list_warehouse_exports, echo_list_warehouse_runs) but cannot create or run them. A run reads the rows Echo received after exported_through (the events' received_at, the audit trail's and failure log's occurred_at) and up to the moment it began, page by page, and streams each page through Stado's content/google.bigquery.insert, which signs in with the service account key the Skarbiec item content-google-bigquery holds; each row's insert id is the source and the row's id, which BigQuery uses to drop a repeated insert. The BigQuery table must already exist with the source table's columns. Only when every page is taken does exported_through move to the run's start; a failed page ends the run failed with its cause and the rows already taken, and the next run reads the window again. The first run loads every row the source holds. The hourly job /api/cron/warehouse-export runs each export whose last run began at least every_hours ago, or that never ran, and records each run in the automation audit trail.

Refusals#

  • A wrong invocation is refused before anything is sent: "export takes list; create --source <table> --project <project> --dataset <dataset> --table <table> --every-hours <hours> --by <name>; remove <export-id>; run <export-id>; runs <export-id>; got <word>", "export <verb> does not take <flag>; it takes …", "<flag> needs a value", "export create needs <flag>" for each of its flags, "export <verb> needs an export id, as export list prints it" and "--every-hours must be a whole number; got <text>".
  • Echo Web's refusal is printed as "Echo Web refused <method> /api/warehouse/… with HTTP <status>: <its answer>": a bad request with "source is required: …", "source must be one of web_analytics_events, mobile_analytics_events, automation_audit, integration_failures; got <source>", "<project_id|dataset_id|table_id> is required: …", "every_hours must be a positive whole number: how many hours apart the export runs; got <value>", "created_by is required: an internal caller has no signed-in user, so it names who is acting" or "export_id is required: …"; not found with "no warehouse export has id <id>"; a conflict with "export <id> is already running since <time>, as run <id>".
  • A run whose load failed is not refused: run writes it failed with the cause, for example "Stado content integration google.bigquery.insert failed with HTTP <status>: <BigQuery's answer>" for a table BigQuery refuses or a key without access, or the same with code rows_refused and BigQuery's insertErrors when it refused rows, in which case it inserted none of that page.