---
title: "Upload a custom rule pack"
method: POST
path: "/v1/trace/rule-packs"
tags: ["Trace"]
---

# Upload a custom rule pack

`POST /v1/trace/rule-packs`

## Request

- Base URL: `https://api.pyai.com`
- URL: `https://api.pyai.com/v1/trace/rule-packs`
- Auth: one of:
  - HTTP bearer
  - API key in header `x-api-key`

Register a custom rule pack (spec §5.3) in the Trace DSL. Structural validation only
here (`pack_id`, `version`, non-empty `rules`); the kernel compiles + deep-validates it
models-side at pull time, and citations/wording are attorney-curated out of band.
Requires the `trace:configure` scope.

## Request body

- TraceRulePackSpec: An authored rule pack in the Trace DSL (rule_pack_schema.json).
  - `pack_id` string, required
  - `version` string, required
  - `jurisdiction` string
  - `legal_status` string: Provenance / attorney-curation status.
  - `rules` object[], required

## Response `201`

Rule pack created

- TraceRulePack
  - `object` string
  - `id` string
  - `pack_id` string
  - `version` string
  - `builtin` boolean: True for PyAI's bundled packs; false for tenant uploads.
  - `jurisdiction` string, nullable
  - `legal_status` string, nullable
  - `etag` string
  - `status` 'active' | 'deprecated'
  - `created_at` integer: Unix ms.
  - `spec` object: The authored DSL (only on the single-pack GET).

## Other responses

- `400`: Invalid request (bad field, unsupported value)
- `401`: Missing or invalid API key (`code: unauthorized`)

---

[API](https://skmtc.dev/pyai/apis/pyai-api.md) · [All operations](https://skmtc.dev/pyai/apis/pyai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/pyai/apis/pyai-api/revisions/271a1539185b?raw)
