> ## Documentation Index
> Fetch the complete documentation index at: https://docs.base44.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Set custom domain redirect

> <Info>This API is in beta. Endpoints, fields, and behavior may still change, so avoid depending on it in production.</Info>

Sends every visitor of this domain to another of the app's domains with a 301 redirect, or stops redirecting when `target_domain` is `null`.

The target has to be another verified custom domain on the same app, and every redirect resolves in one hop. So the target can't already redirect somewhere else, this domain can't already be another domain's target, and two domains can't redirect to each other.

Setting a redirect is limited to 30 requests an hour per caller. Some workspaces have a different limit.

<Warning>The response includes fields beyond the ones documented here. Don't rely on undocumented response fields, as they can change at any time.</Warning>



## OpenAPI

````yaml /developers/references/app-management/app-management-openapi.json put /api/apps/{app_id}/custom-domains/{domain_id}/redirect
openapi: 3.1.0
info:
  title: Base44 App Management API
  version: 1.0.0
servers:
  - url: https://app.base44.com
security:
  - PersonalAccessTokenAuth: []
paths:
  /api/apps/{app_id}/custom-domains/{domain_id}/redirect:
    put:
      summary: Set custom domain redirect
      description: >-
        <Info>This API is in beta. Endpoints, fields, and behavior may still
        change, so avoid depending on it in production.</Info>


        Sends every visitor of this domain to another of the app's domains with
        a 301 redirect, or stops redirecting when `target_domain` is `null`.


        The target has to be another verified custom domain on the same app, and
        every redirect resolves in one hop. So the target can't already redirect
        somewhere else, this domain can't already be another domain's target,
        and two domains can't redirect to each other.


        Setting a redirect is limited to 30 requests an hour per caller. Some
        workspaces have a different limit.


        <Warning>The response includes fields beyond the ones documented here.
        Don't rely on undocumented response fields, as they can change at any
        time.</Warning>
      operationId: >-
        set_domain_redirect_api_apps__app_id__custom_domains__domain_id__redirect_put
      parameters:
        - name: app_id
          in: path
          required: true
          schema:
            type: string
            description: ID of the app the domain belongs to.
            title: App Id
          description: ID of the app the domain belongs to.
          example: 6820f3a4e7b91d003c45a1f2
        - name: domain_id
          in: path
          required: true
          schema:
            type: string
            description: >-
              ID of the custom domain. Get this from [List custom
              domains](/api-reference/list-custom-domains).
            title: Domain Id
          description: >-
            ID of the custom domain. Get this from [List custom
            domains](/api-reference/list-custom-domains).
          example: 68b1c0d4e7b91d003c45a1f7
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetDomainRedirectBody'
      responses:
        '200':
          description: The domain, with its new redirect.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomDomainResource'
        '400':
          description: The domain is disabled, so it can't redirect.
        '401':
          description: Missing or invalid credentials.
        '402':
          description: This workspace's plan doesn't include custom domains.
        '403':
          description: >-
            You don't have access to this app, or you used a workspace API key.
            These endpoints take a personal API key.
        '404':
          description: The app has no custom domain with this ID, or the app doesn't exist.
        '409':
          description: >-
            The address comes from the workspace's app domain
            (`domain_managed_by_workspace`). It follows the app's URL and can't
            be changed on its own.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorEnvelope'
        '422':
          description: >-
            The target is this domain, isn't another verified custom domain on
            the app, or would make a redirect chain or loop.
        '429':
          description: Rate limit reached. Retry later.
      security:
        - PersonalAccessTokenAuth:
            - full_access
components:
  schemas:
    SetDomainRedirectBody:
      properties:
        target_domain:
          anyOf:
            - type: string
            - type: 'null'
          title: Target Domain
          description: >-
            Domain to send this domain's visitors to, or `null` to stop
            redirecting. It has to be another verified custom domain on the same
            app.
          example: www.example.com
      type: object
      title: SetDomainRedirectBody
    CustomDomainResource:
      properties:
        id:
          type: string
          title: Id
          description: >-
            ID of the domain. Pass it as `domain_id` to the other domain
            endpoints.
          example: 68b1c0d4e7b91d003c45a1f7
        domain:
          type: string
          title: Domain
          description: >-
            The domain name, normalized to lower case with any scheme, trailing
            slash and leading `www.` removed.
          example: example.com
        app_id:
          type: string
          title: App Id
          description: ID of the app the domain serves.
          example: 6820f3a4e7b91d003c45a1f2
        disabled:
          type: boolean
          title: Disabled
          description: >-
            Whether Base44 has stopped serving the domain. A disabled domain
            stays attached to the app and keeps its DNS, and serves a
            placeholder page instead of the app.
          example: false
        last_status_check:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Last Status Check
          description: >-
            When [Get custom domain
            status](/api-reference/get-custom-domain-status) last ran for this
            domain, as a UTC timestamp in ISO 8601 format, or `null` if it never
            has.
          example: '2026-08-15T09:10:00'
        last_status_payload:
          anyOf:
            - $ref: '#/components/schemas/CustomDomainStatusPayload'
            - type: 'null'
          description: >-
            The provider's last report on the domain, or `null` until a status
            check has run.
        redirect_target_domain:
          anyOf:
            - type: string
            - type: 'null'
          title: Redirect Target Domain
          description: >-
            The domain that visitors to this one are sent to with a 301
            redirect. The value is `null` when this domain serves the app
            itself.
          example: www.example.com
        provider_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Provider Id
          description: >-
            Names the registrar when the domain was bought through Base44's Wix
            flow. The value is `null` otherwise, which covers both a domain you
            own elsewhere and one bought through the Entri flow, so this isn't a
            purchased-versus-external signal.
          example: wix
      type: object
      required:
        - id
        - domain
        - app_id
        - disabled
      title: CustomDomainResource
      description: A custom domain attached to an app.
    StandardErrorEnvelope:
      properties:
        error:
          $ref: '#/components/schemas/StandardError'
          description: What went wrong.
      type: object
      required:
        - error
      title: StandardErrorEnvelope
      description: The error body returned in the standard envelope.
    CustomDomainStatusPayload:
      properties:
        verificationStatus:
          anyOf:
            - type: string
            - type: 'null'
          title: Verificationstatus
          description: >-
            Whether the provider has verified the domain's DNS. Only `verified`
            means the domain serves the app, and anything else means it doesn't
            yet. Absent until [Get custom domain
            status](/api-reference/get-custom-domain-status) has run once.
          example: verified
      type: object
      title: CustomDomainStatusPayload
      description: What the hosting provider last reported about the domain.
    StandardError:
      properties:
        code:
          type: string
          title: Code
          description: >-
            Stable machine-readable cause of the failure. Match on this, not on
            `message`.
          example: not_found
        message:
          type: string
          title: Message
          description: Human-readable explanation. It isn't a stable contract.
          example: App not found
        details:
          additionalProperties: true
          type: object
          title: Details
          description: >-
            Structured context for the failure, or an empty object when there's
            none.
          example: {}
      type: object
      required:
        - code
        - message
      title: StandardError
  securitySchemes:
    PersonalAccessTokenAuth:
      type: http
      scheme: bearer
      description: >-
        Personal access token, sent as `Authorization: Bearer <token>`. Each
        operation lists the permission it needs: `read_only` or `full_access`. A
        full-access token can call every operation. A read-only token can call
        only the operations that list `read_only`; anything else returns 403
        `read_only_credential_route_not_allowed`.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.