Skip to main content
POST /v1/nql/execute runs a single NQL statement as a workflow. The platform creates a one-task workflow around your statement, starts a run immediately, and returns the workflow and run identifiers so you can track it like any other workflow run. This guide covers what the endpoint accepts, what it returns, and how to follow an execution through to its result.
/v1/nql/execute replaces the deprecated POST /nql/run endpoint. If you have existing code calling /nql/run, see Migrating from /nql/run to /v1/nql/execute.

Prerequisites

  • A Narrative API token
  • Basic familiarity with NQL syntax
  • Familiarity with workflows is helpful but not required

What the endpoint does

  • Runs one NQL statement per request: CREATE MATERIALIZED VIEW, INSERT, UPDATE, DELETE, or EXPLAIN
  • Wraps the statement in a one-task workflow and starts a run immediately
  • Returns 200 with the created workflow and a run_id
  • Honors data_plane_id, compute_pool_id, and create_as_view
  • Turns a REFRESH_SCHEDULE on a CREATE MATERIALIZED VIEW statement into a workflow schedule, so scheduled refreshes run as workflow runs

What the endpoint does not do

  • It does not return query results. Bare SELECT statements are rejected with a 400. To query data and read the results back, create a materialized view and request a sample from the resulting dataset.
  • It does not return the created dataset. For CREATE MATERIALIZED VIEW, the dataset is created when the run executes, after the response is sent. See Getting the created dataset.
  • It does not return a job id. The workflow creates its job shortly after the run starts. See Reaching the job.
  • It does not run MERGE. MERGE ON deduplication is part of materialized view refresh behavior, not a standalone statement.

Executing a statement

The response is the created workflow plus the id of the run that just started:
id is the workflow id and run_id is the run id. You need both to track the execution.

Request parameters

Tracking the run

Poll the workflow’s runs to see whether the statement has finished:
If you only need to know whether the statement succeeded, the run status (running, completed, failed) is enough and you can stop here.

Reaching the job

The workflow’s task creates a job shortly after the run starts — typically within seconds. If you need job-level detail (state transitions, failures, the result payload), list jobs by the run id:
The job identifier field is job_id, not id. Code ported from /nql/run that reads id gets undefined rather than an error.
Because the job is created moments after the run starts, an immediate query can return an empty list — poll until the job appears. The job carries workflow_id and workflow_run_id pointing back at the workflow, so the correlation works in both directions; workflow_id alone returns every job across all runs of that workflow. See Tracking Job Status for polling patterns and backoff.

Getting the created dataset

For CREATE MATERIALIZED VIEW, the dataset does not exist when the response is sent — it is created when the run executes. Two ways to get it:
  1. Await the run, then resolve the dataset by name. You named the view in the statement, so once the run reaches completed, look the dataset up by that name.
  2. Poll the job and read the result. Once the job reaches completed, its result carries the dataset id:
    Then fetch it with GET /datasets/42558.

Canceling a run

Cancel an in-flight execution through the workflow run cancel endpoint:

Errors

Errors are returned as RFC 7807 problem documents with title, status, detail, instance, log_id, and a debug object. See Troubleshooting NQL for how to read these error bodies.

Migrating from /nql/run

Port existing callers of the deprecated endpoint

Workflow Orchestration

Chain multiple operations into one durable workflow

Tracking Job Status

Polling patterns, backoff, and job result handling

Materialized View Syntax

Complete reference for CREATE MATERIALIZED VIEW