ServicesCatalogHTTP APIPublications

Publish changes

POST
/api/catalog/projects/{project_id}/publications

Publish a set of resource and namespace changes as one atomic commit. When an expected version or binding does not agree with the current state, nothing is published and the response contains the conflicts. A request that contains only assertions records a commit but does not change the project state. You must have permission to publish to the project and to change each resource.

Authorization

bearerAuth
headerAuthorizationBearer <token>

Path Parameters

project_id*string

Owning project identifier. Nonempty, at most 128 UTF-8 bytes, with no control characters. Project creation belongs to the project service.

Request Body

application/json
  1. body

Atomic entry-wise publication against a stable branch identity. baseCommitId must be an ancestor of its current head. Compare only submitted domains, permitting disjoint changes since the base; expectedHeadCommitId additionally requires an exact current head. Lists are required, may be empty individually, and are bounded to 1000 entries each. At least one mutation or assertion is required. Assertions participate in conflict checking; an assertion-only publication records a commit. Messages are at most 16384 UTF-8 bytes. The service authenticates the actor, checks state-read permission for assertions including absent resources, and checks resource-kind mutation permissions for all mutated and bound identities.

baseCommitId*catalog.CommitId

Immutable UUIDv7 project commit identity.

Formatuuid
branchId*catalog.BranchId

Stable UUIDv7 branch identity. Rename preserves identity; deletion tombstones it.

Formatuuid
expectedHeadCommitId?|null
idempotencyKey*catalog.IdempotencyKey

Nonempty opaque retry key, at most 128 UTF-8 bytes, scoped to project and authenticated actor. Identical retries return the saved result; reuse for a different operation or request is rejected.

message?string|null
namespace*array<||>
resources*array<|||>
transactionId*catalog.TransactionId

Caller-allocated UUIDv7 publication identity used to recover an uncertain result within a project and authenticated actor scope.

Formatuuid

Response Body

Success

application/json
  1. response

Expected compare-and-swap and namespace constraint conflicts are successful typed responses, not transport errors.

conflict*
type*unknown
curl -X POST 'https://api.spiraldb.dev/api/catalog/projects/string/publications' \  -H 'Content-Type: application/json' \  -d '{  "baseCommitId": "444e6d44-c77c-4d6f-9c8c-82cfd8252d0c",  "branchId": "712f308d-801e-48bc-b072-9c404734ceb7",  "idempotencyKey": "string",  "namespace": [    {      "assert": {        "name": "string",        "parent": {          "prefix": {            "path": [              "string"            ]          },          "type": "prefix"        }      },      "type": "assert"    }  ],  "resources": [    {      "advance": {        "expected": "cc46ff75-488a-4f5d-9162-1798e46c1fcc",        "replacement": "0d5797a7-50c5-42e4-893d-e90cf0476063",        "resourceId": "026d60bb-63a8-407e-bf67-01dcfc6022e6"      },      "type": "advance"    }  ],  "transactionId": "75906707-8c31-479c-b354-aa805c4cefbc"}'
{  "conflict": {    "constraints": [      {        "ambiguousBinding": {          "name": "string",          "parent": {            "prefix": {              "path": [                "string"              ],              "resourceId": "026d60bb-63a8-407e-bf67-01dcfc6022e6"            },            "type": "prefix"          }        },        "type": "ambiguousBinding"      }    ],    "currentCommitId": "d860b6df-6923-4a82-a83e-5fa7b3ce8ada",    "namespace": [      {        "current": "b6f6f63e-cd8b-43b2-a95a-2087cb7f8e11",        "expected": "cc46ff75-488a-4f5d-9162-1798e46c1fcc",        "name": "string",        "parent": {          "prefix": {            "path": [              "string"            ],            "resourceId": "026d60bb-63a8-407e-bf67-01dcfc6022e6"          },          "type": "prefix"        }      }    ],    "resources": [      {        "current": "b6f6f63e-cd8b-43b2-a95a-2087cb7f8e11",        "expected": "cc46ff75-488a-4f5d-9162-1798e46c1fcc",        "resourceId": "026d60bb-63a8-407e-bf67-01dcfc6022e6"      }    ]  },  "type": "conflict"}