Hub API
POST /v1/artifacts
Push a signed artifact to Hub. DPoP authenticated.
Request
POST /v1/artifacts
Authorization: DPoP hub_9f8e7d6c
DPoP: eyJhbGciOiJFZERTQSIsInR5cCI6ImRwb3Arand0In0...
Content-Type: application/json{
"artifact_id": "art_f7e6d5c4b3a2f7e6",
"payload_type": "application/vnd.treeship.action.v1+json",
"envelope_json": "{\"payload\":\"...\",\"payloadType\":\"...\",\"signatures\":[...]}",
"digest": "sha256:abc123...",
"signed_at": 1711500000,
"parent_id": null
}| Field | Type | Required | Description |
|---|---|---|---|
artifact_id | string | Yes | Content-addressed artifact ID |
payload_type | string | Yes | DSSE payload type MIME string |
envelope_json | string | Yes | The complete DSSE envelope as a JSON string |
digest | string | Yes | SHA-256 digest of the PAE bytes, prefixed with sha256: |
signed_at | integer | Yes | Unix timestamp of when the artifact was signed |
parent_id | string or null | No | Parent artifact ID for chain linking |
Authentication
This endpoint requires DPoP authentication. The Authorization header must be DPoP {hub_id}, and the DPoP header must be a valid JWT signed by the hub private key with:
htm: "POST"matching the HTTP methodhtu: "https://api.treeship.dev/v1/artifacts"matching the endpoint URL
See the Hub API overview for full DPoP details.
Response
{
"artifact_id": "art_f7e6d5c4b3a2f7e6",
"hub_url": "https://treeship.dev/verify/art_f7e6d5c4b3a2f7e6",
"rekor_index": 12345
}| Field | Type | Description |
|---|---|---|
artifact_id | string | Echoed artifact ID |
hub_url | string | Public verification URL |
rekor_index | integer or null | Sigstore Rekor log index (null if anchoring was skipped or failed) |
Errors
| Status | Body | Cause |
|---|---|---|
401 | {"error": "invalid DPoP proof"} | DPoP JWT invalid or expired |
401 | {"error": "hub not found"} | Unknown hub ID |
400 | {"error": "missing required field: artifact_id"} | Incomplete request body |
Rekor anchoring
Hub automatically anchors each pushed artifact to Sigstore Rekor. This creates a permanent, publicly auditable record in the transparency log. If Rekor is unavailable, the push succeeds but rekor_index returns null.
Example
curl -X POST https://api.treeship.dev/v1/artifacts \
-H "Authorization: DPoP hub_9f8e7d6c" \
-H "DPoP: eyJhbGciOiJFZERTQSJ9..." \
-H "Content-Type: application/json" \
-d '{
"artifact_id": "art_f7e6d5c4b3a2f7e6",
"payload_type": "application/vnd.treeship.action.v1+json",
"envelope_json": "{...}",
"digest": "sha256:abc123...",
"signed_at": 1711500000,
"parent_id": null
}'In practice, you do not call this endpoint directly. The CLI handles artifact construction, signing, and pushing when you run treeship hub push.