---
title: "Renew a bought domain now"
method: POST
path: "/api/projects/{id}/domains/{domainId}/renew"
tags: ["domains"]
---

# Renew a bought domain now

`POST /api/projects/{id}/domains/{domainId}/renew`

## Request

- Base URL: `https://www.orgo.ai`
- URL: `https://www.orgo.ai/api/projects/{id}/domains/{domainId}/renew`
- Auth: HTTP bearer

Renews the domain for its term (renewal_years) at once, from 30 days before it expires (409 RENEWAL_NOT_DUE before that, with the date). The price (renewal_cents) always comes from your own Orgo credits: credits another member has held for this renewal go back to them first. Send expected_price_cents, the price you were shown: another price answers 409 PRICE_CHANGED with price_cents and charges nothing. Auto-renew need not be on. 200 with the domain, its expires_at moved on. A try that fails leaves nothing behind: when the registry refuses, your credits are given back (502 RENEWAL_FAILED), and neither that nor short credits change when auto-renew tries next. When its answer is lost, the domain shows renewing until the registry confirms (502 RENEWAL_UNKNOWN); nothing is ever charged twice. An expired domain is not renewed here (409 DOMAIN_EXPIRED). Write access, with a session or an account-wide key; 5 an hour per person; one at a time per domain.

## Path parameters

- `id` string, uuid, required
- `domainId` string, uuid, required

## Request body

- object
  - `expected_price_cents` integer: The renewal_cents you were shown.

## Response `200`

{ domain }

- object
  - `domain` RegisteredDomain, required
    - `id` string, uuid, required
    - `domain` string, required
    - `status` 'pending' | 'active', required: pending: the registry has not confirmed it yet; its price is held from the credits until it does.
    - `expires_at` string, date-time, nullable, required: When the term ends, as the registry has it. With auto_renew on it renews before then.
    - `created_at` string, date-time, required
    - `auto_renew` boolean, required: Orgo renews it in its last 14 days from the payer’s Orgo credits. On when bought, off when adopted.
    - `renewal_cents` integer, nullable, required: What the next renewal costs, for renewal_years years. null while there is no price.
    - `renewal_years` integer, required: The years one renewal adds: 1 for most extensions, 2 for a few (like .ai).
    - `renewal_paid_by` 'you' | 'member' | 'null', nullable, required: Whose Orgo credits pay the renewal: yours, or another member’s (whoever turned auto-renew on last, else the buyer). null with auto-renew off.
    - `renewal_state` 'off' | 'scheduled' | 'renewing' | 'retrying' | 'expired', required: off: auto-renew is off and it expires at expires_at. scheduled: the price is taken 14 days before expires_at, and it renews then (only where renewals_enabled). renewing: the renewal is with the registry (it can take up to a day to confirm). retrying: the last try failed (renewal_error) and Orgo tries again every day until expiry. expired: expires_at has passed.
    - `renewal_error` 'insufficient_credits' | 'no_payer' | 'registry_refused' | 'null', nullable, required: Why the last try failed, while retrying: the payer’s credits fall short, the payer can no longer pay (turn auto-renew on, PATCH true, to pay yourself), or the registry refused it.
    - `pointed` object[], required: Names on the domain connected to a computer.
      - `domain` string
      - `computer_id` string, uuid
      - `computer_name` string, nullable
      - `status` string: The custom domain’s status (pending, verifying, active, ...).

## Other responses

- `401`: Unauthenticated.
- `402`: The credits fall short (INSUFFICIENT_CREDITS, with price_cents and available_cents). Add credits, then renew again.
- `403`: A workspace-scoped key (ACCOUNT_KEY_REQUIRED), view-only access (workspace_read_only), no access, or a share-link guest.
- `404`: Domains are not enabled for this account (DOMAINS_NOT_ENABLED), or the workspace has no such domain (DOMAIN_NOT_FOUND).
- `409`: More than 30 days before it expires (RENEWAL_NOT_DUE), expired (DOMAIN_EXPIRED), still being registered (DOMAIN_PENDING), another price than expected_price_cents (PRICE_CHANGED, with price_cents), or this domain is being renewed (RENEWAL_IN_PROGRESS: try again in a few minutes).
- `429`: Five renewals this hour (RATE_LIMITED). retry_after and Retry-After say when.
- `502`: The registry refused it (RENEWAL_FAILED; your credits were given back), has not confirmed it yet (RENEWAL_UNKNOWN), or could not be reached (REGISTRAR_UNAVAILABLE; nothing was sent).
- `503`: Renewing is not available here (RENEWALS_UNAVAILABLE), domains are unavailable (DOMAINS_UNAVAILABLE), or the limit could not be checked (unavailable).

## Changes

- **2026-11-01** `60e768a2bb9d`: 18 info
  - added the optional property `docs_url` to the response with the `402` status
  - added the optional property `docs_url` to the response with the `403` status
  - added the optional property `docs_url` to the response with the `404` status
  - added the optional property `docs_url` to the response with the `409` status
  - …14 more
- **2026-10-26** `3cc83acab9fd`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/orgo/apis/orgo-api/changes/api/projects/:id/domains/:domainId/renew/post.md)

---

[API](https://skmtc.dev/orgo/apis/orgo-api.md) - [All operations](https://skmtc.dev/orgo/apis/orgo-api/llms.txt) - [OpenAPI document](https://skmtc.dev/orgo/apis/orgo-api/revisions/e4c1e7379fa5?raw)
