# Set a workflow tag (/en/docs/api/native/automation/setWorkflowTag)





Point a distribution tag at an existing exact version; tags cannot be versions or version ranges. Moving latest can roll back a release and synchronizes workflow schedules.

`PUT /automation/v1/workflows/{ns}/{name}/dist-tags/{tag}`

## Authentication [#authentication]

`Authorization: Bearer $PRAXIS_API_KEY`

## Request fields [#request-fields]

| Parameter | Type | Description |
| --- | --- | --- |
| path: ns | `string` | required; Namespace, folded to lowercase; matches [a-z0-9][a-z0-9._-]&#123;0,63&#125;. praxis is read-only. |
| path: name | `string` | required; Name, folded to lowercase; matches [a-z0-9][a-z0-9._-]&#123;0,63&#125;. |
| path: tag | `string` | required; Distribution tag. A prerelease (such as 1.3.0-beta.1) requires a tag and it cannot be latest; a tag may only use URL-safe characters (letters, digits and - _ . ! ~ * ' ( )), no spaces or / ? # and no leading or trailing whitespace; it cannot be a version or a version range (such as 1.2.3, ^1, 1.x, *); any other name such as beta, next or debug is allowed. Violations return TAG_INVALID or TAG_REQUIRED with the complete rules in hint. |

### application/json [#applicationjson]

no additional fields.

| Field | Type | Description |
| --- | --- | --- |
| version | `string` | required; An exact canonical semantic version, such as 1.2.0 or 1.3.0-beta.1, not a range. |

## Examples [#examples]

[SDK installation and example environment](/en/docs/api/native/automation)

Set these environment variables to your own resources:

| Variable | Source |
| --- | --- |
| WORKFLOW_NAME | [name returned by creating a workflow](/en/docs/api/native/automation/createWorkflow) |

```bash
: "${WORKFLOW_NAME:?Set WORKFLOW_NAME}"
curl --fail-with-body -X PUT "https://api.deepraxis.ai/automation/v1/workflows/docs-samples/${WORKFLOW_NAME}/dist-tags/sample" \
  -H "Authorization: Bearer $PRAXIS_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
  "version": "1.0.0"
}'
```

```typescript
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.workflows.distTags.set({
  "path": {
    "ns": "docs-samples",
    "name": env("WORKFLOW_NAME"),
    "tag": "sample"
  },
  "body": {
    "version": "1.0.0"
  }
});
console.log(result);
```

## Response [#response]

### HTTP 200 [#http-200]

Success

`application/json`

| Field | Type | Description |
| --- | --- | --- |
| .*.version | `string` | required; Exact version the tag currently points to. |
| .*.updated_at | `string` | required; Time the tag was last moved (RFC 3339 UTC). |
| .*.updated_by | `object` | required; Principal &#123;type, id&#125; 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. |
| .*.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. |
| .*.updated_by.id | `string` | required; Principal identifier whose meaning follows type: a user, API key, agent, run or trigger id. Treat it as an opaque string. |

### Measured response [#measured-response]

HTTP 200

```json
{
  "latest": {
    "version": "1.0.0",
    "updated_at": "2026-10-13T04:57:32.297Z",
    "updated_by": {
      "type": "api_key",
      "id": "key_3e00b8984967"
    }
  },
  "sample": {
    "version": "1.0.0",
    "updated_at": "2026-10-13T04:57:36.329Z",
    "updated_by": {
      "type": "api_key",
      "id": "key_3e00b8984967"
    }
  }
}
```

## Errors [#errors]

| HTTP | Codes and description |
| --- | --- |
| 400 | INVALID_PARAMS: Invalid request parameters, path, cursor, or body format. TAG_INVALID: The tag is invalid: a prerelease cannot use latest; a tag may only use URL-safe characters (no spaces or / ? #); it cannot be a version or range; latest cannot be deleted. The response hint lists the complete rules. INPUT_INVALID: The input does not satisfy the target contract or validation rules. SCHEDULE_INVALID: The schedule or time boundaries are invalid. TIMEZONE_INVALID: The timezone is not a valid IANA timezone. INTERVAL_TOO_SHORT: The schedule interval is shorter than one minute. |
| 403 | NAMESPACE_FORBIDDEN: The namespace is read-only, or the run token does not permit this call. |
| 404 | TARGET_NOT_FOUND: The target does not exist or has an incompatible type. VERSION_NOT_FOUND: The requested version or revision does not exist. |
| 409 | TARGET_ARCHIVED: The target is archived and cannot be used for this operation; action execution error detail includes ns/name. |
| 412 | PRECONDITION_FAILED: The revision, source digest, or concurrent write precondition does not match. |
| 429 | TRIGGER_LIMIT: The tenant has reached the limit of 100 enabled triggers. |
| default | RFC 9457 automation problem. 429 includes Retry-After. |

[Authentication and common errors](/en/docs/api/errors) · Retain the `X-Request-Id` response header for troubleshooting.
