> 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/programs/create-a-shared-requirement-program.md).

# Create a shared requirement program

Use this endpoint to create a shared requirement: a block of requirements, such as a university core, that you build once and link into many programs' audits. It's the only program type you can create through the API. Send `name` and `type: "shared requirement"`, and optionally `base_program` (a program's `id` from [`GET /programs/`](/stellic-partner-api/programs/list-programs.md)) to start from that program's requirements.

## POST /programs/

>

```json
{"openapi":"3.0.0","info":{"title":"Stellic for Developers","version":"1.0"},"tags":[{"name":"Programs","description":"Programs in your catalog and the audits (requirement versions) attached to them. Programs are addressed by `short_name`; audits by internal numeric ID."}],"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":{"CreateProgramRequest":{"type":"object","required":["name","type"],"properties":{"name":{"type":"string","description":"Name of the new program, up to 100 characters. Must not match any existing program's name or `external_id`. It also becomes the program's `external_id` and the name of its first draft audit."},"type":{"type":"string","description":"Must be the literal `shared requirement` (case-sensitive). No other program type can be created through the API today.","enum":["shared requirement"]},"base_program":{"type":"integer","description":"Internal `id` of an existing program (from `GET /programs/`) whose audit tree is copied into the new program. The published audit with the lowest ID is used (usually the oldest); if there is none, a draft is used. Omit to start from an empty draft. Compliance-requirement programs are rejected."}}},"CreateProgramResponse":{"type":"object","properties":{"success":{"type":"boolean"},"program":{"$ref":"#/components/schemas/ProgramSummary"}}},"ProgramSummary":{"type":"object","description":"A program as the programs and audits endpoints return it.","properties":{"id":{"type":"integer","description":"Internal database ID of the program. Only needed where an endpoint asks for it, such as `base_program`."},"name":{"type":"string"},"external_id":{"type":"string","description":"The program's `short_name`, the identifier you use in path parameters and in your program feed. For a shared requirement program it equals `name`."},"shared_requirement":{"type":"object","description":"Present only for programs of type `shared requirement`. `id` is the value to send as `shared_requirement_id` when linking this shared requirement into an audit.","properties":{"id":{"type":"integer"}}}}},"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":{"/programs/":{"post":{"tags":["Programs"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProgramRequest"}}}},"responses":{"201":{"description":"Program created with one draft audit named `name`, empty or copied from `base_program`. For a shared requirement program `external_id` equals `name`. `shared_requirement.id` is the value you send as `shared_requirement_id` when adding this shared requirement to another audit; it is usable there only after the program's audit is published.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProgramResponse"}}}},"400":{"description":"Validation failure.\n\nCommon causes:\n- Missing `name` - returns `'name' is required`\n- Missing `type` - returns `'type' is required`\n- `scope` present in the body - returns `Currently, scope providing is not supported`\n- `type` is a known program type other than `shared requirement` - returns `Currently, only type 'shared requirement' is supported. Received: {type}`\n- `type` is not a program type at all - returns `Invalid program type: {type}. Currently, only 'shared requirement' is supported.`\n- A program with the same name exists - returns `Program with name '{name}' already exists`\n- `base_program` does not exist - returns `Base program with id {base_program} not found`\n- `base_program` has no published or draft audit to copy - returns `No audit found in the given base program`\n- `base_program` is not an integer - returns `Field 'id' expected a number but got '<value>'.`\n- `name` matches another program's `external_id`, or is longer than 100 characters - returns the database's error message","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 to `Compliance requirements are not available via the API.`, when `base_program` is a compliance requirement.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"client_ip":{"type":"string"}}}}}}}}}}}
```

#### What happens after the call

* The program is created with `external_id` set to `name`, along with one draft audit, also named `name`.
* Without `base_program`, the draft is empty. With it, the draft copies the base program's published audit; if the base program has several, the one with the lowest ID, which is usually the oldest. If it has none, one of its drafts is copied.
* The block can't be linked into other audits until you publish its draft. No student is affected until an audit that links it is published.

#### Notes

{% hint style="warning" %}
**Publish the draft before you link the block.** Until then, linking it returns `Shared Requirement Does Not Exist`. Find the draft with [`GET /programs/{program_short_name}/audits`](/stellic-partner-api/programs/list-a-program-s-audits.md), build it, and [publish it](/stellic-partner-api/audits/publish-a-draft-audit.md).
{% endhint %}

* **The name must be new across every program.** A name that another program already uses returns `Program with name '<name>' already exists`. Because `name` becomes the `external_id`, it also can't match another program's `external_id` or be longer than 100 characters; either returns a 400 carrying the database's message.
* **URL-encode `external_id` in paths,** since it's the name, spaces included: `/programs/University%20Core/audits`.
* **`scope` isn't accepted.** A body with a `scope` key returns `Currently, scope providing is not supported`.
* **`base_program` takes the numeric `id`, not the `external_id`.** An unknown ID returns `Base program with id <id> not found`. A base program with no published or draft audit returns `No audit found in the given base program`. A compliance requirement returns a 403.
* **Errors return 400 with `{"error": "<message>"}`.**

#### Related APIs

* [`GET /programs/{program_short_name}/audits`](/stellic-partner-api/programs/list-a-program-s-audits.md) to find the new draft.
* [`POST /audits/{audit_id}/requirements/{parent_req_id}/subrequirements`](/stellic-partner-api/audits/add-a-sub-requirement.md) to build the block, and to link it into other audits with `type: "shared_requirement"` and `data.shared_requirement_id`.
* [`POST /audits/{audit_id}/publish`](/stellic-partner-api/audits/publish-a-draft-audit.md) to publish the block.
