> For the complete documentation index, see [llms.txt](https://docs.stellic.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stellic.com/stellic-partner-api/audits/publish-a-draft-audit.md).

# Publish a draft audit

Use this endpoint to make a draft or under-review audit live. The call checks the audit, publishes it, and moves students onto it before it returns; recalculating their progress and search data continues in the background. Check `status` in the response, then poll [`GET /audits/{audit_id}/publishing_status`](/stellic-partner-api/audits/check-an-audit-s-publishing-status.md) until `publishing_in_progress` is `false` before you read progress or publish again.

## POST /audits/{audit\_id}/publish

>

```json
{"openapi":"3.0.0","info":{"title":"Stellic for Developers","version":"1.0"},"tags":[{"name":"Audits","description":"Read, draft, edit, and publish an audit's requirement tree. Edits go to a draft; publishing recomputes student progress in the background."}],"servers":[{"url":"https://{institution}.stellic.com/partnerapi/v1","variables":{"institution":{"default":"{institution}","description":"Your institution's Stellic subdomain: the part before `.stellic.com` in the URL you use to sign in. It becomes the host in every request, as in `https://{institution}.stellic.com/partnerapi/v1/...`. Replace the `{institution}` placeholder with your subdomain before sending."}}}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Personal Access Token issued by your Stellic integration partner. Send it as `Authorization: Bearer <token>` on every request. One token per institution; do not share across environments."}},"schemas":{"AuditSummary":{"type":"object","properties":{"id":{"type":"integer","description":"Internal database ID of the audit. Use it on the `/audits/` endpoints."},"name":{"type":"string","description":"Audit name. A draft created from a published audit carries the published name plus a `-draft` suffix until it is published."},"status":{"type":"string","description":"One of `draft`, `review`, `published`. Other statuses exist internally but are not served.","enum":["draft","review","published"]}}},"ErrorMessage":{"type":"object","description":"Error envelope used by the programs, audits, and requirements endpoints.","properties":{"error":{"type":"string","description":"Human-readable reason. Match on it if you need to branch; the strings on each endpoint page are verbatim."}}}}},"paths":{"/audits/{audit_id}/publish":{"post":{"tags":["Audits"],"parameters":[{"name":"audit_id","in":"path","required":true,"description":"Internal numeric ID of the draft (or under-review) audit to publish. Pass the draft's ID, not the ID of the published version it was copied from.","schema":{"type":"integer"}}],"responses":{"200":{"description":"The synchronous part of publishing finished. `status` is `published` when the audit went live: the previous published version is archived, this audit takes over its name (the `-draft` suffix is gone), and students matching the audit's criteria are already on the new version. `status` is `review` when the token's account can edit but not publish this audit; in that case nothing was published and the audit is waiting for a reviewer in the app. Post-publish recalculation continues in the background; poll `GET /audits/{audit_id}/publishing_status`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditSummary"}}}},"400":{"description":"The audit cannot be published as it stands. Nothing changed.\n\nCommon causes:\n- The requirement review (for example a requirement with children but no `anyxof` or `minxcourses` constraint, or an `anyxof` with no children) or the student-impact review (changes that would remove student exceptions, planned courses, or template courses) reported findings - returns `This audit has errors/caveats that require manual review and cannot be published via the API.` Fix the draft, or publish it in Stellic where the review can be acknowledged.\n- Another publish of this audit is running, or one failed less than a minute ago - returns `['Cannot publish this audit right now.']`\n- The published audit this draft replaces still has its `update_req_tree` task unfinished (including failed) - returns `['Audit publishing is still in progress. Please wait until it is done, before you can publish again.']`\n- The audit's name contains `-draft` but it isn't linked to a published audit - returns `['Cannot publish this audit. Please contact the Stellic team.']`\n- Conflicting degree requirements - returns `['Cannot publish this audit because it has conflicting Degree Requriements']`\nMessages from Stellic's checks come wrapped in `['...']`, as shown.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorMessage"}}}},"401":{"description":"Missing or invalid Bearer token.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"403":{"description":"Your IP address isn't on the allowlist for this endpoint. Contact Stellic to add it; the response includes the `client_ip` Stellic saw. Also returned, with only `error` set, when the audit isn't a draft or under review (`Can only publish draft or under-review audits.`), is a general requirement or degree requirement (`General requirement and diploma requirement audits cannot be published via the API.`), or belongs to a compliance requirement (`Compliance requirements are not available via the API.`).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"client_ip":{"type":"string"}}}}}},"404":{"description":"No audit has this ID: `{\"detail\": \"No Audit matches the given query.\"}`.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}}}}}}}
```

#### What happens after the call

During the call:

* The requirements and the effect on students are reviewed. Any finding stops the publish with a 400, and nothing changes.
* The audit becomes `published`, and its root takes the program's name.
* If it's the draft of a published audit, the old version is archived and the draft takes its name, so `-draft` is dropped. Access to the old version carries over.
* On a regular program, students who match the audit's `year` are reassigned: each gets the published audit that fits them best, which may be this one. Students whose program is certified with an audit attached, locked, or archived, or who have a diploma awarded, stay where they are.
* On a shared requirement, the block is marked published, and its new content reaches the audits that link it in the background.

In the background: three tasks update student records, course-to-requirement matching, and student audits and search. They're listed on the publishing status.

#### Notes

{% hint style="warning" %}
**A 200 can mean "sent for review".** If the token's account can edit the audit but not publish it, the audit goes to review instead: `status` is `review`, nothing is published, and a reviewer approves it in Stellic.
{% endhint %}

* **Publish the draft's ID.** A published audit returns a 403 with `Can only publish draft or under-review audits.`
* **Review findings can't be overridden here.** They return `This audit has errors/caveats that require manual review and cannot be published via the API.` Common causes are a requirement with children but no `anyxof` or `minxcourses` rule, an `anyxof` with no children, and changes that would remove student exceptions or planned courses. Fix the draft, or publish it in Stellic, where the review can be acknowledged.
* **Wait for the previous publish.** While the published audit's student-records task is still running, publishing its next draft returns `['Audit publishing is still in progress. Please wait until it is done, before you can publish again.']`. A publish that overlaps another returns `['Cannot publish this audit right now.']`.
* **Don't put `-draft` in a standalone audit's name.** An audit whose name contains `-draft` but isn't linked to a published audit returns `['Cannot publish this audit. Please contact the Stellic team.']`.
* **There's no unpublish.** Draft the published audit, reverse the changes, and publish again.
* **General requirement and degree requirement audits can't be published here** (403). Shared requirements can.
* **An unknown ID returns a 404,** `{"detail": "No Audit matches the given query."}`. A compliance requirement's audit returns a 403.

#### Related APIs

* [`GET /audits/{audit_id}/publishing_status`](/stellic-partner-api/audits/check-an-audit-s-publishing-status.md) to follow the background work.
* [`POST /audits/{audit_id}/draft`](/stellic-partner-api/audits/get-or-create-a-draft-of-a-published-audit.md) to get the draft to publish.
* [`GET /student/{student_username}/progress/summary`](/stellic-partner-api/student/read-a-student-s-progress-summary.md) to read progress once publishing finishes.
