Skip to main content

Container registry API endpoints

These endpoints manage Cloider container registry projects. A project holds your container images at registry.cloider.com/<project>/<repository>:<tag>. You create and delete projects, change their visibility and storage limit, browse and delete repositories, images and tags, and set the policies that delete old images (retention) and protect tags (immutability). Pushing and pulling images is done with docker and a registry token, not with these endpoints.

All paths are relative to https://cloider.com/api. See Authentication for the token header.

At a glance​

MethodPathAccess
GET/registry/projectsRead
POST/registry/projectsWrite
GET/registry/projects/optionsRead
GET/registry/projects/:hashed_idRead
GET/registry/projects/:hashed_id/statusRead
GET/registry/projects/:hashed_id/summaryRead
GET/registry/projects/:hashed_id/usageRead
PUT/registry/projects/:hashed_id/settingsWrite
DELETE/registry/projects/:hashed_idWrite
GET/registry/projects/:hashed_id/repositoriesRead
POST/registry/projects/:hashed_id/repositories/deleteWrite
GET/registry/projects/:hashed_id/artifactsRead
POST/registry/projects/:hashed_id/artifacts/deleteWrite
POST/registry/projects/:hashed_id/tags/deleteWrite
GET/registry/projects/:hashed_id/retentionRead
PUT/registry/projects/:hashed_id/retention/rulesWrite
PUT/registry/projects/:hashed_id/retention/scheduleWrite
POST/registry/projects/:hashed_id/retention/runsWrite
GET/registry/projects/:hashed_id/retention/runsRead
GET/registry/projects/:hashed_id/retention/runs/:run_idRead
GET/registry/projects/:hashed_id/retention/runs/:run_id/tasks/:task_idRead
GET/registry/projects/:hashed_id/immutabilityRead
POST/registry/projects/:hashed_id/immutabilityWrite
PUT/registry/projects/:hashed_id/immutability/:rule_idWrite
DELETE/registry/projects/:hashed_id/immutability/:rule_idWrite
PUT/registry/projects/:hashed_id/immutable-tagsWrite

The project object​

{
"hashed_id": "r4c8z",
"name": "acme",
"public": false,
"apps": false,
"storage_limit_gi": 5,
"status": "Ready",
"size_bytes": 1288490188,
"size_sampled_at": "2026-10-20T09:00:07.402118Z",
"host": "registry.cloider.com",
"url": "registry.cloider.com/acme",
"created_at": "2026-09-21T11:48:30.991204Z"
}
FieldTypeDescription
hashed_idstringThe project's id
namestringThe project name, the first path segment of every image. Unique across Cloider and fixed once created
publicbooleantrue when anyone can pull without logging in. Pushing always needs a token
appsbooleantrue for the project Cloider made to hold your apps' images. It can't be deleted and its images and policies are managed by Cloider
storage_limit_giintegerThe most the project may store, in GiB. A push that would go past it is refused
statusstringCreating, Ready, Terminating or Failed
size_bytesintegerBytes stored as of the last usage sample. Billing follows what is stored
size_sampled_atstring or nullWhen size_bytes was measured
hoststringThe registry host, registry.cloider.com
urlstringThe prefix of every image in the project, <host>/<name>
created_atstringWhen the project was created

GET /registry/projects/:hashed_id also returns username, the account's registry username that every registry token logs in with.

List projects​

GET /registry/projects

Returns the account's projects, newest first, without deleted ones.

Access: any token.

curl https://cloider.com/api/registry/projects \
-H "Authorization: Bearer $CLOIDER_TOKEN"

The response is a list of project objects.

Get registry options​

GET /registry/projects/options

Returns what the create form needs: the registry host and the storage limits.

Access: any token.

curl https://cloider.com/api/registry/projects/options \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
{"host": "registry.cloider.com", "default_storage_limit_gi": 5, "max_storage_limit_gi": 20}

Create a project​

POST /registry/projects

Creates a project. Like a bucket, it is created while the request runs, so the answer also tells you whether the name was free.

Access: Read & Write token.

FieldTypeRequiredDescription
namestringYes3 to 63 characters: lower case letters, digits and -, with at least one letter, starting and ending with a letter or digit, no --. Shared by every Cloider account
publicbooleanNotrue to allow anonymous pulls. Default false
storage_limit_giintegerNo1 to 20. Default 5
immutable_tagsbooleanNotrue so that no tag can be pushed over or deleted. Default false
curl -X POST https://cloider.com/api/registry/projects \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "acme", "storage_limit_gi": 10}'
Response
{"hashed_id": "r4c8z"}
StatusFieldMessage
400nameProject name must not be empty, Project name must be at least 3 characters, Project name must not exceed 63 characters, Project name can only have lowercase letters, numbers and "-", Project name must start and end with a letter or a number, with no "--", Project name must have at least one letter, Project name is reserved, This project name is already taken
400storage_limit_giStorage limit must be between 1 and 20 GB
400_Free plan users can not create more than one project. UPGRADE NOW! (the apps project doesn't count)
400_Your account is suspended. Upgrade to a paid plan to continue using our services.
400_The container registry isn't available at the moment!, Operation failed, Couldn't create the project!
403_This API token is read only!, You have read-only access to this account, you can not create projects!

Get a project​

GET /registry/projects/:hashed_id

Returns one project, with the account's registry username added.

Access: any token.

curl https://cloider.com/api/registry/projects/r4c8z \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
{
"hashed_id": "r4c8z",
"name": "acme",
"public": false,
"apps": false,
"storage_limit_gi": 10,
"status": "Ready",
"size_bytes": 1288490188,
"size_sampled_at": "2026-10-20T09:00:07.402118Z",
"host": "registry.cloider.com",
"url": "registry.cloider.com/acme",
"username": "acme",
"created_at": "2026-09-21T11:48:30.991204Z"
}

Get a project's status​

GET /registry/projects/:hashed_id/status

Returns the status as plain text, for example Ready. A deleted project answers 404.

Access: any token.

Get live storage use​

GET /registry/projects/:hashed_id/summary

Returns the project's repository count and storage use as the registry counts them right now. size_bytes on the project is only the last usage sample.

Access: any token. The project must be Ready.

curl https://cloider.com/api/registry/projects/r4c8z/summary \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
{"repository_count": 4, "used_bytes": 1288490188, "limit_bytes": 10737418240}

Errors: 400 with The project must be ready to read its storage. or Couldn't read the project, try again in a moment!.

Get a project's usage​

GET /registry/projects/:hashed_id/usage

Returns the project with its storage usage and cost: the last 31 days in daily_usage and this month's totals in monthly_usage (avg_storage_usage in GiB, storage_total_cost, total_cost, days, forecast_this_month, forecast_next_month), plus forecast_rest_of_day, date and month. It has the same shape as a bucket's usage.

Access: any token.

curl https://cloider.com/api/registry/projects/r4c8z/usage \
-H "Authorization: Bearer $CLOIDER_TOKEN"

Change visibility and storage limit​

PUT /registry/projects/:hashed_id/settings

Sets whether the project is public and its storage limit. Both fields are applied, so always send both, even to change only one.

Access: Read & Write token. The project must be Ready.

FieldTypeRequiredDescription
publicbooleanYestrue to allow anonymous pulls, false for private
storage_limit_giintegerYes1 to 20. Leaving it out sends 0, which is refused
curl -X PUT https://cloider.com/api/registry/projects/r4c8z/settings \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"public": false, "storage_limit_gi": 15}'

The response is the updated project object.

StatusMessage
400Storage limit must be between 1 and 20 GB (on storage_limit_gi)
400The project must be ready to change its settings.
400Another change to this project is in progress, try again in a moment!
400Couldn't change the project's settings, try again in a moment!
403This API token is read only!, You have read-only access to this account, you can not change projects!

Delete a project​

DELETE /registry/projects/:hashed_id

Deletes the project with every repository and image in it. This can't be undone. The project goes to Terminating while its repositories are deleted, then disappears, and its status answers 404.

Access: Read & Write token.

curl -X DELETE https://cloider.com/api/registry/projects/r4c8z \
-H "Authorization: Bearer $CLOIDER_TOKEN"

The response is the account's project list, with this project Terminating.

StatusMessage
400This project is still being created!, This project is already being deleted!
400This project holds your apps' images and is managed by Cloider, it can't be deleted.
400Another change to this project is in progress, try again in a moment!
403This API token is read only!, You have read-only access to this account, you can not delete projects!

List repositories​

GET /registry/projects/:hashed_id/repositories

Lists the project's repositories, the image names under it (api in registry.cloider.com/acme/api:1.0), 25 per page by default.

Access: any token. The project must be Ready.

Query parameterRequiredDescription
qNoOnly repositories whose name contains this. Lower case letters, digits, ., _, - and /, up to 128 characters
pageNoPage number, from 1. Default 1
page_sizeNo1 to 100. Default 25
curl -G https://cloider.com/api/registry/projects/r4c8z/repositories \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
--data-urlencode "q=api"
Response
{
"repositories": [
{
"name": "api",
"artifact_count": 12,
"pull_count": 340,
"created_at": "2026-09-21T12:02:10.118Z",
"updated_at": "2026-10-19T16:44:52.906Z"
}
],
"total": 1
}

name is without the project, and can contain slashes (team/api). artifact_count is the number of images. total is the number of repositories matching, across pages.

List images in a repository​

GET /registry/projects/:hashed_id/artifacts

Lists the images (artifacts) in one repository, newest first, 25 per page by default, with their tags, size and platforms.

Access: any token. The project must be Ready.

Query parameterRequiredDescription
repositoryYesThe repository name, for example api or team/api
pageNoDefault 1
page_sizeNo1 to 100. Default 25
curl -G https://cloider.com/api/registry/projects/r4c8z/artifacts \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
--data-urlencode "repository=api"
Response
{
"artifacts": [
{
"digest": "sha256:3f1c9a8e0d7b6c5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a",
"tags": [
{"name": "1.4.2", "pushed_at": "2026-10-19T16:44:50Z", "immutable": false},
{"name": "latest", "pushed_at": "2026-10-19T16:44:51Z", "immutable": false}
],
"size": 48213504,
"pushed_at": "2026-10-19T16:44:50Z",
"pulled_at": "2026-10-20T08:12:03Z",
"type": "IMAGE",
"platforms": [
{"os": "linux", "architecture": "amd64"},
{"os": "linux", "architecture": "arm64"}
]
}
],
"total": 12
}
FieldDescription
digestThe image's content digest, sha256: and 64 hex characters. The stable way to name an image
tagsIts tags, each with name, pushed_at and whether an immutability rule protects it (immutable)
sizeSize in bytes
pushed_at, pulled_atWhen it was pushed and last pulled (null if never)
typeThe artifact type, for example IMAGE
platformsThe os and architecture (and variant where there is one) of each image a multi-platform image contains

Errors: 400 with Invalid repository on repository, 404 It doesn't exist any more, reload and try again! for a repository that is gone.

Delete a repository​

POST /registry/projects/:hashed_id/repositories/delete

Deletes a repository and every image in it.

Access: Read & Write token.

FieldTypeRequiredDescription
repositorystringYesThe repository name
curl -X POST https://cloider.com/api/registry/projects/r4c8z/repositories/delete \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"repository": "old-worker"}'
Response
{"success": true}

Delete an image​

POST /registry/projects/:hashed_id/artifacts/delete

Deletes one image, by digest, with every tag on it.

Access: Read & Write token.

FieldTypeRequiredDescription
repositorystringYesThe repository name
digeststringYesThe image's digest, sha256:...
curl -X POST https://cloider.com/api/registry/projects/r4c8z/artifacts/delete \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"repository": "api", "digest": "sha256:3f1c9a8e0d7b6c5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a"}'
Response
{"success": true}

Remove a tag​

POST /registry/projects/:hashed_id/tags/delete

Takes one tag off an image. The image stays under its other tags. An image left with no tag at all is removed by the registry's nightly cleanup.

Access: Read & Write token.

FieldTypeRequiredDescription
repositorystringYesThe repository name
digeststringYesThe digest of the image the tag is on
tagstringYesThe tag, for example latest
curl -X POST https://cloider.com/api/registry/projects/r4c8z/tags/delete \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"repository": "api", "digest": "sha256:3f1c9a8e0d7b6c5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a", "tag": "latest"}'
Response
{"success": true}

Errors of the three delete endpoints​

StatusMessage
400Invalid repository (on repository), Invalid repository or image, Invalid repository, image or tag
400A tag immutability rule protects this tag. Disable the rule in the Policy tab to delete it.
400This image is in use by another image in the repository, delete that one first. (an image a multi-platform index points to)
400This project holds your apps' images and is managed by Cloider. Deleting an app deletes its images.
400The project must be ready to browse its images., Couldn't reach the registry, try again in a moment!
403This API token is read only!, You have read-only access to this account, you can not delete images!
404It doesn't exist any more, reload and try again!

Retention policies​

A retention policy deletes old images automatically. Its rules say which images to keep; a run deletes every image in the repositories the rules cover that no rule keeps. Runs happen on a schedule or when you start one, and a dry run shows what would be deleted without deleting anything. See Retention policies for examples.

The retention rule object​

{
"repositories": {"match": "matching", "patterns": ["**"]},
"tags": {"match": "excluding", "patterns": ["latest", "v*"]},
"untagged": true,
"keep": "latest_pushed",
"count": 10,
"disabled": false
}
FieldTypeDescription
repositoriesobjectWhich repositories the rule covers: match is matching or excluding, patterns is 1 to 20 patterns. ** matches everything, * stays within one path segment, ? matches one character
tagsobjectWhich tags the rule looks at, in the same form. Tag patterns use letters, digits, ., _, -, * and ?
untaggedbooleanWhether images without a tag count as matching the tag patterns too
keepstringalways, latest_pushed, latest_pulled, pushed_within_days or pulled_within_days
countintegerFor latest_pushed and latest_pulled, how many images to keep (1 to 10000). For the within_days ones, the number of days (1 to 3650). Ignored for always
disabledbooleantrue to keep the rule but not apply it

The schedule object​

{"every": "daily", "minute": 0, "hour": 3, "weekday": 0, "cron": "0 0 3 * * *"}
FieldDescription
everynone, hourly, daily, weekly, or custom for a schedule set outside the dashboard
minute, hourThe time of day in UTC, 0 to 59 and 0 to 23
weekdayFor weekly, 0 (Sunday) to 6 (Saturday)
cronThe schedule as a cron expression with seconds. Read only

Get the retention policy​

GET /registry/projects/:hashed_id/retention

Returns the project's retention rules and schedule. A project without a policy has no rules and the schedule none.

Access: any token. The project must be Ready.

curl https://cloider.com/api/registry/projects/r4c8z/retention \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
{
"rules": [
{
"repositories": {"match": "matching", "patterns": ["**"]},
"tags": {"match": "matching", "patterns": ["**"]},
"untagged": true,
"keep": "latest_pushed",
"count": 10,
"disabled": false
}
],
"schedule": {"every": "daily", "minute": 0, "hour": 3, "weekday": 0, "cron": "0 0 3 * * *"}
}

A policy that was changed outside the dashboard can't be read and answers 400 with This project's policies were changed outside the dashboard, contact support to edit them.

Replace the retention rules​

PUT /registry/projects/:hashed_id/retention/rules

Replaces all retention rules. The schedule is kept. An empty list removes every rule.

Access: Read & Write token. Not allowed on the apps project.

FieldTypeRequiredDescription
rulesobject listYesUp to 15 retention rules
curl -X PUT https://cloider.com/api/registry/projects/r4c8z/retention/rules \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"rules": [
{
"repositories": {"match": "matching", "patterns": ["**"]},
"tags": {"match": "matching", "patterns": ["**"]},
"untagged": true,
"keep": "latest_pushed",
"count": 10
}
]
}'

The response is the saved policy, as in Get the retention policy.

StatusFieldMessage
400repositories, tagsChoose matching or excluding, Enter at least one pattern, ** for all, Enter at most 20 patterns, "..." isn't a valid pattern. ...
400keepChoose what the rule keeps
400countKeep between 1 and 10000 images, Enter between 1 and 3650 days
400_A policy holds at most 15 rules., Two of the rules are the same, change or delete one of them., The registry refused the policy, check its rules and try again.
400_This project holds your apps' images and is managed by Cloider, its policies can't be changed.
403_This API token is read only!, You have read-only access to this account, you can not change policies!

Set the retention schedule​

PUT /registry/projects/:hashed_id/retention/schedule

Sets when the retention policy runs by itself. The rules are kept.

Access: Read & Write token.

FieldTypeRequiredDescription
everystringYesnone (only manual runs), hourly, daily or weekly. custom keeps a custom schedule as it is
minuteintegerNo0 to 59
hourintegerNo0 to 23, UTC. Used by daily and weekly
weekdayintegerNo0 (Sunday) to 6. Used by weekly
curl -X PUT https://cloider.com/api/registry/projects/r4c8z/retention/schedule \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"every": "weekly", "minute": 30, "hour": 2, "weekday": 0}'

The response is the saved policy. Errors are on schedule: Choose how often the policy runs and Choose a valid time.

Run the retention policy​

POST /registry/projects/:hashed_id/retention/runs

Starts a retention run now. With dry_run it only records what it would delete, so you can check the rules first.

Access: Read & Write token.

FieldTypeRequiredDescription
dry_runbooleanNotrue for a dry run. Default false
curl -X POST https://cloider.com/api/registry/projects/r4c8z/retention/runs \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"dry_run": true}'
Response
{"success": true}

The run happens in the background: list the runs to follow it. Errors: Add a retention rule, or enable one, to run the policy. and The policy is already running, wait for it to finish. (both 400).

List retention runs​

GET /registry/projects/:hashed_id/retention/runs

Lists the project's retention runs, newest first.

Access: any token.

Query parameterRequiredDescription
pageNoDefault 1
page_sizeNo1 to 100. Default 25
curl https://cloider.com/api/registry/projects/r4c8z/retention/runs \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
{
"runs": [
{
"id": 57,
"status": "succeeded",
"trigger": "manual",
"dry_run": true,
"started_at": "2026-10-20T09:14:02Z",
"finished_at": "2026-10-20T09:14:09Z"
}
],
"total": 1
}

status is pending, running, stopped, failed or succeeded; trigger is manual or schedule; finished_at is null while the run is going. Poll this list until the latest run is no longer pending or running.

List a run's repositories​

GET /registry/projects/:hashed_id/retention/runs/:run_id

Lists what a run did per repository: one task per repository, with the number of images it looked at and kept.

Access: any token.

Path parameterDescription
run_idThe run's id from the runs list
curl https://cloider.com/api/registry/projects/r4c8z/retention/runs/57 \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
{
"tasks": [
{"id": 311, "repository": "api", "status": "succeeded", "total": 24, "retained": 10}
],
"total": 1
}

page and page_size work as for the runs list. A malformed run_id answers 400 Invalid run.

See what a run did in a repository​

GET /registry/projects/:hashed_id/retention/runs/:run_id/tasks/:task_id

Lists every image a task looked at and what happened to it.

Access: any token.

curl https://cloider.com/api/registry/projects/r4c8z/retention/runs/57/tasks/311 \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
{
"images": [
{"digest": "sha256:3f1c9a8e0d7b6c5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a", "tags": ["1.4.2", "latest"], "result": "kept"},
{"digest": "sha256:9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b", "tags": ["1.1.0"], "result": "deleted"}
]
}

result is kept, deleted, immutable (kept because an immutability rule protects it) or failed. In a dry run, deleted means "would be deleted".

Tag immutability​

An immutability rule protects tags from being pushed over or deleted, so that api:1.4.2 always means the same image. Immutable tags is the simple version: one rule that protects every tag in every repository. See Immutable tags.

The immutability rule object​

{
"id": 12,
"repositories": {"match": "matching", "patterns": ["**"]},
"tags": {"match": "matching", "patterns": ["v*"]},
"disabled": false
}

repositories and tags take the same patterns as retention rules. id is the rule's numeric id.

List immutability rules​

GET /registry/projects/:hashed_id/immutability

Returns the project's immutability rules and whether immutable tags are on.

Access: any token. The project must be Ready.

curl https://cloider.com/api/registry/projects/r4c8z/immutability \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
{
"rules": [
{"id": 12, "repositories": {"match": "matching", "patterns": ["**"]}, "tags": {"match": "matching", "patterns": ["v*"]}, "disabled": false}
],
"immutable_tags": false
}

immutable_tags is true when an enabled rule protects every tag (**) in every repository (**).

Add an immutability rule​

POST /registry/projects/:hashed_id/immutability

Adds a rule. A project holds at most 15.

Access: Read & Write token. Not allowed on the apps project.

FieldTypeRequiredDescription
repositoriesobjectYes{"match": "matching" or "excluding", "patterns": [...]}
tagsobjectYesSame form, tag patterns
disabledbooleanNotrue to add it switched off
curl -X POST https://cloider.com/api/registry/projects/r4c8z/immutability \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"repositories": {"match": "matching", "patterns": ["**"]}, "tags": {"match": "matching", "patterns": ["v*"]}}'

The response is the full rule list with immutable_tags, as in List immutability rules. Errors: the pattern errors on repositories and tags, The project already has a rule like this one., and A project holds at most 15 immutability rules..

Change an immutability rule​

PUT /registry/projects/:hashed_id/immutability/:rule_id

Replaces a rule's patterns and its disabled flag. The body is the same as for adding one. The response is the full rule list. A rule that doesn't exist answers 404 It doesn't exist any more, reload and try again!; a malformed rule_id answers 400 Invalid rule.

Access: Read & Write token.

curl -X PUT https://cloider.com/api/registry/projects/r4c8z/immutability/12 \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"repositories": {"match": "matching", "patterns": ["**"]}, "tags": {"match": "matching", "patterns": ["v*"]}, "disabled": true}'

Delete an immutability rule​

DELETE /registry/projects/:hashed_id/immutability/:rule_id

Deletes a rule. The response is the remaining rule list.

Access: Read & Write token.

curl -X DELETE https://cloider.com/api/registry/projects/r4c8z/immutability/12 \
-H "Authorization: Bearer $CLOIDER_TOKEN"

Turn immutable tags on or off​

PUT /registry/projects/:hashed_id/immutable-tags

Turns on the rule that protects every tag in the project, or removes it. Other immutability rules aren't touched.

Access: Read & Write token.

FieldTypeRequiredDescription
immutable_tagsbooleanYestrue to protect every tag, false to stop
curl -X PUT https://cloider.com/api/registry/projects/r4c8z/immutable-tags \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"immutable_tags": true}'

The response is the rule list with immutable_tags. With 15 rules already, turning it on answers A project holds at most 15 immutability rules, delete one in the Policy tab first.

Errors of the policy endpoints​

Besides the errors listed with each endpoint, every policy change can answer:

StatusMessage
400The project must be ready to change its policies.
400Another change to this project is in progress, try again in a moment!
400This project holds your apps' images and is managed by Cloider, its policies can't be changed.
400This project's policies were changed outside the dashboard, contact support to edit them.
403This API token is read only!, You have read-only access to this account, you can not change policies!