Release Evidence API
The Release Evidence API returns a signed, structured evidence package for a given release. It is designed for compliance workflows — specifically the Smartshares audit trail requirement — and for any system that needs to attest to the state of a release at a point in time.
Use Case: Smartshares Integration
Smartshares requires a digitally verifiable record of every software release, including:
- Who approved the release and when.
- Which commits and pull requests were included.
- Whether CI tests passed.
- Whether pre-release quality checklists were completed.
The Release Evidence API provides all of this in a single, signed JSON package that your compliance system can store and verify independently.
Endpoint
GET /api/v1/releases/:id/evidence
Authorization: Bearer <api-key>
Required permission: read:release
Response Body — EvidencePackage
{
"schemaVersion": 1,
"generatedAt": "2026-05-14T10:00:00.000Z",
"status": "complete", // "complete" | "incomplete"
"release": {
"id": "rel_…",
"name": "Sprint 42",
"version": "v2.4.0",
"status": "released",
"releasedAt": "2026-05-01T00:00:00.000Z",
"riskLevel": "medium",
"projectId": "proj_…",
"projectName": "Acme Platform"
},
"approvalChain": {
"instanceId": "inst_…",
"overallStatus": "approved",
"stages": [
{
"name": "Engineering Lead",
"approver": "Alice Smith",
"approvedAt": "2026-04-30T15:22:00.000Z",
"comment": "LGTM",
"status": "approved"
}
]
},
"qualityChecklists": [
{
"name": "Release Readiness",
"items": [
{
"label": "Regression suite passed",
"completedBy": "Alice Smith",
"completedAt": "2026-04-30T14:00:00Z",
"isCompleted": true
}
]
}
],
"entrySummary": {
"totalCount": 12,
"byStatus": { "solved": 10, "deployed": 2 },
"releasedOrCompleted": [
{ "id": "ent_…", "title": "Fix login redirect", "status": "solved" }
]
},
"githubEvidence": {
"entries": [
{
"id": "ent_…",
"title": "Fix login redirect",
"status": "solved",
"commits": [
{
"sha": "a1b2c3d",
"author": "Alice Smith",
"message": "fix: correct redirect after OAuth login",
"committedAt": "2026-04-29T11:00:00.000Z",
"url": "https://github.com/acme/platform/commit/a1b2c3d",
"verified": false,
"ciResult": "passed",
"testsPassed": 312,
"testsFailed": 0,
"testsSkipped": 4
}
],
"pullRequests": [
{
"number": 847,
"title": "Fix login redirect",
"mergedAt": "2026-04-29T12:00:00.000Z",
"url": "https://github.com/acme/platform/pull/847"
}
]
}
]
},
"completenessScore": 87
}
status field
"complete"— the release is incompletedorreleasedstate."incomplete"— any other state; the evidence is preliminary.
completenessScore (0–100)
Computed as the mean of three fractions:
- Fraction of entries with at least one linked commit.
- Fraction of entries with at least one passing CI run.
- All checklist items complete → 1.0, otherwise 0.0.
Signature Verification
When a signing key is configured for your organisation, every evidence response includes:
X-Align-Evidence-Signature: sha256=<hex-digest>
X-Align-Evidence-Key-Prefix: evk_9a3b1c2d
The digest is HMAC-SHA256(rawKey, canonicalJsonBody).
rawKeyis the full signing key returned once byPOST /api/settings/evidence-key. Store it immediately — it is never shown again.canonicalJsonBodyis the raw response body with no extra whitespace.
Generating a Signing Key
- Go to Settings → Evidence Key.
- Click Generate Key.
- Copy the full key (
evk_<64hex>). Store it securely.
Verifying in Node.js
const crypto = require("crypto");
function verifyEvidence(rawBody, signatureHeader, rawKey) {
if (!signatureHeader?.startsWith("sha256=")) return false;
const received = signatureHeader.slice(7);
const expected = crypto
.createHmac("sha256", rawKey)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(received, "hex"),
Buffer.from(expected, "hex")
);
}
Verifying in Python
import hmac, hashlib
def verify_evidence(raw_body: bytes, signature_header: str, raw_key: str) -> bool:
if not signature_header or not signature_header.startswith("sha256="):
return False
received = bytes.fromhex(signature_header[len("sha256="):])
expected = hmac.new(
raw_key.encode(),
raw_body,
hashlib.sha256,
).digest()
return hmac.compare_digest(received, expected)
Key Rotation
When rotating the signing key:
- Generate a new key from Settings → Evidence Key → Rotate.
- Update your compliance system with the new key.
- Verify the new key works by fetching a known release evidence and verifying the signature.
- Remove the old key from your secrets manager.