Automation

Create a script

Save a TypeScript script as an editable draft for later reuse; this does not publish or start a run.

Save a TypeScript script as an editable draft for later reuse; this does not publish or start a run. Choose your own namespace without registering it first; praxis is read-only. Scripts and workflows share names within the tenant; a duplicate returns NAME_TAKEN. The draft is a source string with a default-exported function, for example export default async (input: {name: string}) => ({greeting: "Hello, " + input.name});. To test it, pass that source and language=ts to praxis.automation.runs.create without publishing. To publish later, use the returned draft.revision as expected_draft_revision.

POST /automation/v1/scripts

Authentication

Authorization: Bearer $PRAXIS_API_KEY

Request fields

ParameterTypeDescription
header: Idempotency-Keystringoptional; Optional; 1–256 characters. Within 24 hours, the same key replays the first response with Idempotent-Replayed: true; a different request body returns 422; an in-flight request returns 409. minLength: 1; maxLength: 256

application/json

no additional fields.

FieldTypeDescription
namespacestringrequired; Choose a namespace without prior registration; praxis is read-only. Folded to lowercase; matches [a-z0-9][a-z0-9.-]{0,63}. pattern: "^[a-zA-Z0-9][a-zA-Z0-9.-]{0,63}$"
namestringrequired; Name, folded to lowercase; matches [a-z0-9][a-z0-9.-]{0,63}. pattern: "^[a-zA-Z0-9][a-zA-Z0-9.-]{0,63}$"
descriptionstringoptional; Description, at most 1,000 characters. maxLength: 1000
draftstringoptional; Editable source: TypeScript for scripts, YAML for workflows. Defaults to an empty string on creation.
labelsobjectoptional; At most 50 labels; keys contain 1–40 characters and values at most 500 characters.

Examples

curl --fail-with-body -X POST "https://api.deepraxis.ai/automation/v1/scripts" \
  -H "Authorization: Bearer $PRAXIS_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
  "namespace": "docs-samples",
  "name": "sample-scripts",
  "draft": "export default async (input: { n: number }) => ({ answer: input.n + 1 });"
}'
import { createAutomationClient } from '@deepraxis/sdk/automation';

function env(name: string): string {
  const value = process.env[name];
  if (!value) throw new Error(`Set ${name}`);
  return value;
}
const automation = createAutomationClient({
  apiKey: env('PRAXIS_API_KEY'),
  baseUrl: 'https://api.deepraxis.ai',
  maxRetries: 0,
  timeoutMs: 90_000,
});
const result = await automation.scripts.create({
  "body": {
    "namespace": "docs-samples",
    "name": "sample-scripts",
    "draft": "export default async (input: { n: number }) => ({ answer: input.n + 1 });"
  }
});
console.log(result);

Response

HTTP 200

Success

HeaderTypeDescription
Idempotent-ReplayedbooleanPresent and true when replaying the first response for this key.

application/json

FieldTypeDescription
draftobjectrequired; The editable draft of a script or workflow; publishing takes the draft or a run's source. no additional fields.
draft.sourcestringrequired; Draft source: TypeScript for scripts, YAML for workflows.
draft.revisionstringrequired; Draft revision tag (ETag); send it as expected_draft_revision when publishing or as If-Match when updating the draft; a mismatch returns 412.
draft.updated_atstringrequired; Time the draft was last changed (RFC 3339 UTC).
draft.updated_byobjectrequired; Principal {type, id} injected by the gateway that says who initiated or acted. This service does not resolve names; the console resolves them in batches. no additional fields.
draft.updated_by.type"user" / "api_key" / "agent" / "run" / "trigger"required; Principal type. user is a signed-in user; api_key is a platform API key; agent is an agent; run is an action performed by a run itself (for example a parent run); trigger is a trigger.
draft.updated_by.idstringrequired; Principal identifier whose meaning follows type: a user, API key, agent, run or trigger id. Treat it as an opaque string.
idstringrequired; Definition id, prefixed scr_ for scripts and wf_ for workflows; calls normally use namespace and name.
kind"script" / "workflow"required; Orchestration kind. script is a TypeScript script that executes once; workflow is a YAML workflow made of steps that can wait for events, timers or child runs and can be suspended.
namespacestringrequired; Namespace; references take the form namespace/name@version.
namestringrequired; Name; with namespace it is unique within the tenant, and scripts and workflows share one namespace (duplicates return 409 NAME_TAKEN).
descriptionstringrequired; Free-text description, at most 1000 characters.
labelsobjectrequired; User-defined string key and value tags for grouping and list filtering (labels[key]=value); keys must not start with praxis.
ownerstringrequired; Tenant that owns the definition, injected by the gateway; treat it as an opaque string.
latest_versionnull / objectrequired; The published version the latest tag points to, as {version, published_at}; null if nothing is published.
latest_version (variant 2).versionstringrequired; Version number (semver) of the latest published version.
latest_version (variant 2).published_atstringrequired; Time that version was published (RFC 3339 UTC).
dist_tagsobjectrequired; Map from dist-tag to the exact version it points to, for example latest to 1.2.0; ns/name@tag resolves through it.
draft_changedbooleanrequired; true when the draft content (digest) differs from the latest version, meaning there are unpublished changes.
latest_runnull / objectrequired; Summary of the most recent run of this definition, or null if it has never run.
latest_run (variant 2).idstringrequired; Run id (run_ prefix); pass it to runs.retrieve.
latest_run (variant 2).numbernull / numberrequired; Increasing sequence number of the run within its script or workflow.
latest_run (variant 2).status"running" / "completed" / "faulted" / "cancelled" / "pending" / "waiting" / "suspended"required; Run status. pending is created but not started; running is executing; waiting means a workflow is waiting on an event, timer or child run; suspended means a workflow was suspended; cancelled was cancelled; faulted failed; completed finished successfully.
latest_run (variant 2).created_atstringrequired; Time the run was created (RFC 3339 UTC).
latest_run (variant 2).current_waitnull / objectrequired; The wait point currently open, or null when the run is not waiting.
latest_run (variant 2).current_wait (variant 2).idstringrequired; Wait point id, prefixed wait_; use it as wait_id when completing an event wait.
latest_run (variant 2).current_wait (variant 2).run_idstringrequired; Id (run_) of the run this wait belongs to.
latest_run (variant 2).current_wait (variant 2).kind"event" / "timer" / "child"required; Wait kind. event waits for an external event that can be submitted with runs.completeWait; timer waits until resume_at; child waits for a child run to finish.
latest_run (variant 2).current_wait (variant 2).state"cancelled" / "open" / "resolved" / "expired"required; Wait point state. open is still waiting; resolved was satisfied; expired passed its expires_at; cancelled was cancelled and can no longer be satisfied.
latest_run (variant 2).current_wait (variant 2).tasknull / objectrequired; The workflow step {reference, name} that produced the wait; null when there is no such step.
latest_run (variant 2).current_wait (variant 2).task (variant 2).referencestringrequired; JSON Pointer of the step, for example /do/2/wait_payment.
latest_run (variant 2).current_wait (variant 2).task (variant 2).namestringrequired; Step name, the key in the workflow YAML.
latest_run (variant 2).current_wait (variant 2).resume_atnull / stringrequired; For kind=timer, the instant the run resumes (RFC 3339 UTC); null for other kinds.
latest_run (variant 2).current_wait (variant 2).event_typenull / stringrequired; For kind=event, the event type being awaited; null for other kinds.
latest_run (variant 2).current_wait (variant 2).child_run_idnull / stringrequired; For kind=child, the id of the child run being awaited; null for other kinds.
latest_run (variant 2).current_wait (variant 2).created_atstringrequired; Time the wait point was created (RFC 3339 UTC).
latest_run (variant 2).current_wait (variant 2).expires_atnull / stringrequired; Time the wait point expires (RFC 3339 UTC), or null if it has no deadline.
latest_run (variant 2).current_wait (variant 2).resolved_atnull / stringrequired; Time the wait point was resolved (RFC 3339 UTC), or null if still open.
stats_7dobjectrequired; Run statistics for the last seven days, bucketed by the day each run ended and updated when runs finish. no additional fields.
stats_7d.runsnumberrequired; Number of runs that ended in the last seven days, in any terminal status.
stats_7d.failuresnumberrequired; How many of those runs ended faulted.
archived_atnull / stringrequired; Archive time, or null while not archived. An archived name stays reserved and cannot be reused.
created_atstringrequired; Creation time (RFC 3339 UTC).
updated_atstringrequired; Time of the last update (RFC 3339 UTC).

Measured response

HTTP 200

{
  "id": "scr_00mv67lwvh08624c70ef824a0d8b14b0315c88452e",
  "owner": "tnt_3a9759864ccb4e00",
  "kind": "script",
  "namespace": "docs-samples",
  "name": "sample-scripts-1791867412840-b05e8a",
  "description": "",
  "labels": {},
  "latest_version": null,
  "dist_tags": {},
  "draft_changed": true,
  "latest_run": null,
  "stats_7d": {
    "runs": 0,
    "failures": 0
  },
  "archived_at": null,
  "created_at": "2026-10-13T04:57:19.277Z",
  "updated_at": "2026-10-13T04:57:19.277Z",
  "draft": {
    "source": "export default async (input: { n: number }) => ({ answer: input.n + 1 });",
    "revision": "draft_00mv67lwvh333793ba7d9e47cb89b5fd8b43fb4fa3",
    "updated_at": "2026-10-13T04:57:19.277Z",
    "updated_by": {
      "type": "api_key",
      "id": "key_3e00b8984967"
    }
  }
}

Errors

HTTPCodes and description
400INVALID_PARAMS: Invalid request parameters, path, cursor, or body format.
403NAMESPACE_FORBIDDEN: The namespace is read-only, or the run token does not permit this call.
409IDEMPOTENCY_IN_FLIGHT: A request with the same idempotency key is still in progress. NAME_TAKEN: The name is already used by this tenant.
422IDEMPOTENCY_KEY_MISMATCH: The idempotency key was already used for different request content.
defaultRFC 9457 automation problem. 429 includes Retry-After.

Authentication and common errors · Retain the X-Request-Id response header for troubleshooting.

Export

On this page