The ask call

POST https://api.datagoat.io/v1/ask, or the dg_ask tool over MCP. It is the one call: a record, questions and cases go in, and one answer per question comes back. This page is the reference. The ideas behind it are in The record, Questions and Answers.

Request

{
  "data": {"dataset_id": "sample:saas_churn"},
  "entity_column": "customer_id",
  "subject_kind": "org",
  "questions": {
    "churn": {"type": "yesno", "outcome_column": "churned", "outcome_is_desirable": false},
    "risk":  {"type": "score", "outcome_column": "churned", "outcome_is_desirable": false}
  },
  "cases": {"ids": ["cust_0001"]},
  "idempotency_key": "3f1c…"
}
Field Required
data yes the record: exactly one of dataset_id, rows, csv, fetch_url (with optional fetch_headers). The record
entity_column yes the column that names each case
subject_kind yes person, org, object, event or other
questions yes 1 to 8 questions, keyed by id. Questions
cases for yesno, score, choice {"ids": [...]} or {"rows": [...]}, up to 10,000. Omit to rank the whole record.
time_column with a shape; optional for a table the time column; orders rows, so cases by id read each case's latest row
shape no how to read a record that isn't one row per case. Shapes
acknowledge_decision_support when subject_kind is person must be true
band no adds band, band_reason and max_autonomy to each case
idempotency_key no a retry with the same key, within 24 hours, returns the first answer and never fits or bills twice

Question fields

Field Types
type all yesno, score, choice or rank
outcome_column all but choice with option_outcomes the yes/no column to learn
outcome_is_desirable all; required for choice whether the outcome is wanted
positive_values all the values of the outcome column that mean yes
refit_of all the model_ref of an earlier answer, for drift
levels, cuts score score
option_column, options or option_outcomes choice choice
top_k rank 1 to 1,000, default 20

Response

200 with {"status": "done", "answers": {…}, "fits_run", "billable_decisions", …}, or 202 with {"status": "pending", "task_id", "retry_after_ms"} while a first fit runs. Poll dg_poll (POST /v1/poll) with the task_id. Every field is described in Answers.

Errors

Errors are RFC 9457 problems (application/problem+json) with code, detail, remedy, and field when an argument is at fault. A refusal is not an error: it is an answer with state: "refused".

Code Field Fix
invalid_request the field named The request doesn't match the schema. The detail says how.
entity_column_missing, time_column_missing, outcome_column_missing, option_column_missing the column field Name a column of the record. The remedy lists them.
positive_values_required questions.<id>.positive_values Say which values of the outcome column mean yes.
positive_values_differ questions.<id>.positive_values The option_outcomes columns use different yes values. Pass the ones they share.
outcome_not_binary, outcome_constant questions.<id>.outcome_column Name a yes/no column that holds both yes and no.
unknown_case_id cases.ids Send ids that appear in the entity column, or send the rows.
row_not_scoreable cases Send every column the model uses, with the same types.
unknown_dataset data.dataset_id The dataset was deleted (24 hours after last use) or isn't in this workspace. Store it again.
shape_invalid, shape_empty shape Shapes
test_key_samples_only A test key works on the samples only. Create a live key at datagoat.io/keys.
scope_required Reporting outcomes and attesting need a key with "Can report outcomes", or an OAuth sign-in.
lever_token_invalid, post_value_unreadable lever_token, post_value (dg_attest) Pass the token exactly as received, and the new value in the record's units.
dataset_sealed dataset_id (dg_add_dataset) The dataset has been asked about, so it takes no more rows. Store a new one.
idempotency_conflict idempotency_key The key was used for a different request. Use a new one.
engine_timeout, engine_unavailable Retry; the SDKs mark these retryable.

Cost

One decision per answered case, $0.00002 each ($20 per million). A fit is $0.01 after 1,000 free each month. Refusals, not_yet, declined cases and the samples are free. Answers.