/v1/projectsAPI keyCreate or update a project
Upsert a project — a body without `projectId` mints a new 8-character id.
The same route creates and updates. Send a `projectId` you already own to rename it or re-parent it; omit it to create.
On an account key this is the provisioning call: creating needs no `X-Project-Id` (there is no project yet) and requires an Editor-level key. The signed-in session calls the same route.
`parentProjectIds` establishes inheritance: a child project reads its ancestors' cells and entities through the same retrieval calls, so a per-repository child under one organization parent gives every child the shared context without copying it.
Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | required | Human-readable project name. |
| projectId | string | optional | Existing project to update. Omit to mint a new id. |
| parentProjectIds | string[] | optional | Projects this one inherits readable context from. Each must be a project you can access. |
curl -X POST "https://runlog-7613480744.us-central1.run.app/v1/projects" \
-H "Authorization: Bearer $RUNLOG_API_KEY" \
-H "X-Project-Id: p7Kd2mQx" \
-H "Content-Type: application/json" \
-d '{
"name": "LingCode — acme/checkout",
"parentProjectIds": [
"orgRootA1"
]
}'{
"ancestorProjectIds": [
"orgRootA1"
],
"createdAt": "2026-08-07T18:20:04Z",
"name": "LingCode — acme/checkout",
"ownerUid": "u_8Kd0Zq",
"parentProjectIds": [
"orgRootA1"
],
"projectId": "p7Kd2mQx",
"updatedAt": "2026-08-07T18:20:04Z"
}Errors
| Status | error | When |
|---|---|---|
| 400 | name is required | The body carried no `name`. |
| 404 | project not found | A named parent is not reachable by you. Answering 404 rather than 403 keeps projects non-enumerable — you cannot probe a parent's existence. |
| 400 | invalid request body | The body is not JSON, or exceeds the 1 MB request-body cap. |
| 401 | invalid API key | The `Authorization` header is missing, malformed, or names a revoked key. |
| 400 | name the target project via the X-Project-Id header or projectId query | No project was named and the key is not bound to one. |
| 429 | rate limit exceeded | You passed 60 requests/minute on this key. `Retry-After` carries the seconds to wait. |
| 500 | internal error | The relay failed to serve the request. Retry with backoff; the cause is logged server-side against your request. |