Parkside Subdomain & CDN — Frontend API Contract

Request/response models, error states, and async operation lifecycles for the Free Subdomains APIs. Package: ParksideSubdomainService.

Modelschemas · states · errors
GetSubdomainAvailabilitysync 200
CreateSubdomainasync 202
Associateasync 202
Disassociateasync 202
Transferasync 202
DeleteSubdomainasync 202
GetSubdomainssync 200
CreateDistribution (CDN)async 202

Data Model

Subdomain states
RESERVED
A 15-min exclusive name reservation placed by GetSubdomainAvailability(reserve=true).
PROVISIONING
CreateSubdomain accepted; ACM cert + shadow hosted zone + NS delegation being set up.
UNATTACHED
Provisioned and ready, not associated with any resource.
ATTACHING
UpdateSubdomainAssociation(ASSOCIATE) in progress.
ATTACHED
Associated with a Lightsail resource (CDN, container service, LB, instance).
DETACHING
UpdateSubdomainAssociation(DISASSOCIATE) in progress.
TRANSFERRING
UpdateSubdomainAssociation(TRANSFER) in progress.
IMPLICIT
Structural parent (no DS2 resource/cert). A level-1 subdomain deleted while children survive becomes IMPLICIT.
DELETED
Released and in post-delete reclaim cooldown. NS delegation removed immediately; still listed until cooldown expires, then removed.

Transient states are in-flight during an async operation; stable states are resting points; terminal is post-delete cooldown. Poll GetSubdomains until the operation reports isTerminal=true.

Operation status
StatusMeaning
NotStartedOperation created, not yet picked up.
StartedAsync workflow running (isTerminal=false).
SucceededTerminal success (isTerminal=true).
FailedTerminal failure (isTerminal=true). errorCode/errorDetails populated; subdomain reverts to its prior stable state (or is removed for a failed create).
Error responses (what the customer receives)

These are the PAPIS / Lightsail exceptions the SDK/console actually returns. The error body is { "__type", "code", "message" }. Branch on code, not on the exception type — quota and every conflict share OperationFailureException. HTTP shown is the modeled (webapp) status; note the AWS SDK returns every client error as 400 and every fault as 500 (it retries 500s). Internal faults return ServiceException with the generic message "Internal Server Error" and no code.

Exception (__type)HTTPcodemessage
InvalidInputException400InvalidInputInput is missing or invalid — several templated messages (e.g. "The specified subdomain name is not valid. It must be 1 to 63 characters…", "The specified target resource ARN is not valid.").
InvalidInputException400BlockedNameThe specified subdomain name uses a reserved label. Please choose a different name and try again.
OperationFailureException400TooManyReservationsYou have reached the maximum number of subdomain reservations (5). Please try again after a reservation expires or is claimed.
OperationFailureException400NameExistsThe specified subdomain name is unavailable / already exists. Please choose a different name and try again.
OperationFailureException400AlreadyReservedThe specified subdomain name has already been reserved or created. Please choose a different name and try again.
OperationFailureException400DeleteInProgressThe subdomain is still being deleted. Please try again in a few moments.
OperationFailureException400StateConflictThe subdomain must be in the UNATTACHED state to associate a resource / the ATTACHED state to disassociate or transfer.
OperationFailureException400ResourceAlreadyInUseThe specified resource is already attached to another subdomain. Please detach it first or choose a different resource.
OperationFailureException400ResourceAlreadyAttachedThe subdomain is already associated with the requested resource.
OperationFailureException400UpdateConflictThe subdomain was modified by another request. Please retrieve the latest state and try again.
OperationFailureException400SubdomainAttachedThe subdomain is attached to a resource. Please disassociate it before deleting.
OperationFailureException400SubdomainProvisioningThe subdomain is still provisioning. Please try again once provisioning completes.
OperationFailureException400SubdomainInCooldownThe subdomain has already been deleted and is in its reclaim cooldown. It cannot be deleted again.
OperationFailureException400DeleteConflictThe subdomain could not be deleted. Please try again later.
NotFoundException404SubdomainNotFoundThe specified subdomain could not be found.
ServiceException500InternalServerErrorSomething went wrong. Please try again later. (One generic message for every 500.)
PAPIS front-door errors

Thrown by PAPIS before the subdomain service is called — feature gating, region gating, authentication, and IAM authorization (primary + dependent actions). (The subdomain service itself never returns 401/403.) Most front-door errors carry no code — branch on __type + HTTP; only the region gate sets code: "UnsupportedOperation".

Exception (__type)HTTPcodeApplies toWhenExample message
UnauthenticatedException401— noneall operationsThe caller is not authenticated (missing or invalid identity).Please authenticate.
AccessDeniedException403— noneall subdomain operationsThe Lightsail free-subdomains feature (subdomain_fac) is not enabled for the account. Also returned by CreateDistribution when a subdomainName is supplied and the account is not enabled.Sorry, you are not authorized to perform the request.
AccessDeniedException403— noneall subdomain operationsPrimary-action IAM authorization: the caller's policy does not allow the operation's own action (lightsail:GetSubdomainAvailability / CreateSubdomain / UpdateSubdomainAssociation / DeleteSubdomain / GetSubdomains) on the subdomain resource. aws:ResourceTag conditions on the subdomain are enforced.You are not authorized to perform: lightsail:CreateSubdomain on the specified resource.
AccessDeniedException403— noneAssociate, Disassociate, TransferDependent-action IAM authorization: the caller's policy does not allow the required action on the target CDN distribution (ASSOCIATE/TRANSFER need lightsail:AttachCertificateToDistribution; DISASSOCIATE and the detach side of TRANSFER need lightsail:DetachCertificateFromDistribution). aws:ResourceTag conditions on the distribution are enforced.You are not authorized to perform: lightsail:AttachCertificateToDistribution on the specified resource.
InvalidInputException400UnsupportedOperationall subdomain operations (prod/preprod)Called outside us-east-1. Subdomains are IAD-only.Subdomain-related APIs are only available in the us-east-1 Region. Please set your Region configuration to us-east-1 to create, view, or edit subdomain resources.
Async operation failure codes

These are NOT HTTP errors — the call returns 202 and later the polled operation reports status=Failed with these operation.errorCode / operation.errorDetails values (seen via GetSubdomains). All internal async failures share one message.

operation.errorCodeOperationoperation.errorDetails
CreateFailedCreateSubdomainThe operation could not be completed. Please try again later.
UpdateFailedUpdateSubdomainAssociationThe operation could not be completed. Please try again later.
DeleteFailedDeleteSubdomainThe operation could not be completed. Please try again later.
InternalErrorany (caught exception)The operation could not be completed. Please try again later.
TargetNotFoundUpdateSubdomainAssociationThe specified target resource %s could not be found in %s.
SourceNotFoundUpdateSubdomainAssociationThe specified source resource %s could not be found in %s.
UnsupportedTypeUpdateSubdomainAssociationThe specified resource %s is not a supported attachable resource type.
ResourceNotReadyUpdateSubdomainAssociationThe specified resource %s is currently updating. Please try again shortly.
Backend validations

All request validation runs in the service (not the Smithy model), synchronously and before any state change, so a violation returns a modeled exception (PAPIS surfaces InvalidInputException / OperationFailureException) rather than a framework 500.

Input / rule areaValidationOn failure (code → customer exception)
subdomainName — presenceMust be non-blank.InvalidInput → InvalidInputException (400)
subdomainName — depthAt most 2 dot-separated labels (app = 1, api.app = 2).InvalidInput (400)
subdomainName — length & format≤ 63 chars total; each label matches ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ (lowercase letters, digits, hyphens; no leading or trailing hyphen). Punycode/IDN labels (xn--) are rejected to prevent homograph spoofing.InvalidInput (400)
subdomainName — reserved labelsNo label may be on the reserved blocklist. Enforced on GetSubdomainAvailability and CreateSubdomain only.BlockedName → InvalidInputException (400)
actionMust be exactly one of ASSOCIATE, DISASSOCIATE, TRANSFER (UpdateSubdomainAssociation).InvalidInput (400)
targetResourceArn (ASSOCIATE / TRANSFER)Required. Must be a well-formed Lightsail resource ARN whose account equals the caller. Malformed, or account != caller -> TargetArnInvalid.InvalidInput (400)
targetResourceArn resource typeThe ARN's type token must be a supported attachable type (Phase 1: Distribution). Parsed from the ARN, no DS2 call.UnsupportedType (400)
targetResourceArn region (CDN)For a Distribution the ARN's region must equal the stage's CDN region (us-east-1 in prod/preprod).InvalidInput (400) (message: "CDN distributions are only supported in us-east-1.")
pageToken (GetSubdomains)Must be a valid opaque token, and cannot be combined with subdomainName.InvalidInput (400)
reservation capacity (reserve=true)Account must hold fewer than 5 unexpired reservations.TooManyReservations → OperationFailureException (400)
name availability (CreateSubdomain)Name must not already exist, be reserved/created by the caller, or still be deleting.NameExists / AlreadyReserved / DeleteInProgress → OperationFailureException (400)
state precondition (Update / Delete)ASSOCIATE requires UNATTACHED; DISASSOCIATE and TRANSFER require ATTACHED; Delete is blocked while PROVISIONING, while ATTACHED, or during the post-delete cooldown.StateConflict / SubdomainProvisioning / SubdomainAttached / SubdomainInCooldown → OperationFailureException (400)

Policy limits: 30 subdomains per account · 5 concurrent reservations · 15-minute reservation TTL · 30-day (+ 0–7 day jitter) delete cooldown for once-attached names · 24-hour transfer window.

Structures

CreateSubdomainRequest

FieldTypeReqAllowed / constraintsNotes
subdomainNameStringyes1–63 chars total; ≤ 2 dot-separated labels; each label lowercase [a-z0-9] with optional internal hyphens (no leading/trailing hyphen); no punycode (xn--)Label path, e.g. "app" or "api.app".

CreateSubdomainResult

FieldTypeReqAllowed / constraintsNotes
subdomainSubdomainSummaryyesstate=PROVISIONING; arn populated.
operationOperationyesstatus=Started.

UpdateSubdomainAssociationRequest

FieldTypeReqAllowed / constraintsNotes
subdomainNameStringyes1–63 chars total; ≤ 2 dot-separated labels; each label lowercase [a-z0-9] with optional internal hyphens (no leading/trailing hyphen); no punycode (xn--)
actionStringyesASSOCIATE | DISASSOCIATE | TRANSFERASSOCIATE | DISASSOCIATE | TRANSFER.
targetResourceArnStringnoARN of the target Lightsail resource (e.g. arn:aws:lightsail:us-east-1:123456789012:Distribution/<id>). Self-describing (region, account, resource type, id) — there is no separate resource-name/resource-region/resource-type input; region/account/type are read from the ARN, so dependent-action authorization runs against the ARN with no cross-region DS2 lookup. Required for ASSOCIATE and TRANSFER; omit for DISASSOCIATE.

DeleteSubdomainRequest

FieldTypeReqAllowed / constraintsNotes
subdomainNameStringyes1–63 chars total; ≤ 2 dot-separated labels; each label lowercase [a-z0-9] with optional internal hyphens (no leading/trailing hyphen); no punycode (xn--)

GetSubdomainAvailabilityRequest

FieldTypeReqAllowed / constraintsNotes
subdomainNameStringyes1–63 chars total; ≤ 2 dot-separated labels; each label lowercase [a-z0-9] with optional internal hyphens (no leading/trailing hyphen); no punycode (xn--)
reserveBooleannoboolean; true → 15-min RESERVED hold (max 5 concurrent/account)Place a 15-min reservation; returns reservationExpiresAt.

GetSubdomainAvailabilityResult

FieldTypeReqAllowed / constraintsNotes
availableBooleanyesboolean
reservationExpiresAtTimestampnoPresent only when reserve=true and available.
subdomainNameStringno1–63 chars total; ≤ 2 dot-separated labels; each label lowercase [a-z0-9] with optional internal hyphens (no leading/trailing hyphen); no punycode (xn--)Echoes the validated name.

GetSubdomainsRequest

FieldTypeReqAllowed / constraintsNotes
subdomainNameStringno1–63 chars total; ≤ 2 dot-separated labels; each label lowercase [a-z0-9] with optional internal hyphens (no leading/trailing hyphen); no punycode (xn--)Single-lookup mode. Cannot combine with pageToken.
pageTokenStringnoopaque continuation token; not combinable with subdomainNameList-mode continuation. Cannot combine with subdomainName.

GetSubdomainsResult

FieldTypeReqAllowed / constraintsNotes
subdomainSubdomainSummarynoSingle-lookup mode.
subdomainsSubdomainSummary[]noList mode (roots with nested children).
nextPageTokenStringnoPresent when more results remain.

SubdomainSummary

FieldTypeReqAllowed / constraintsNotes
subdomainNameStringyes1–63 chars total; ≤ 2 dot-separated labels; each label lowercase [a-z0-9] with optional internal hyphens (no leading/trailing hyphen); no punycode (xn--)
arnStringnoARN of the subdomain (assigned at creation).
fqdnStringyese.g. app.amazonlightsail.com.
depthIntegeryes1 (level-1) or 2 (level-2)Label depth (1 = level-1).
stateSubdomainStateyesRESERVED | PROVISIONING | UNATTACHED | ATTACHING | ATTACHED | DETACHING | TRANSFERRING | IMPLICIT | DELETEDSee States.
attachedResourceAttachedResourcenoPresent when ATTACHED.
dnsRecordDnsRecordno
createdAtTimestampno
parentFqdnStringno
childrenSubdomainSummary[]noNested children (list mode only).

AttachedResource

FieldTypeReqAllowed / constraintsNotes
resourceNameStringyes
resourceTypeStringyesResource-type token parsed from the Lightsail resourceArn, e.g. DistributionThe resource-type token parsed from the Lightsail resourceArn, e.g. Distribution. NOT the internal AttachableResourceType enum (that is an internal dispatch detail, never surfaced).
regionStringnoAWS Region code, e.g. us-east-1
resourceArnStringnoThe Lightsail resource ARN (e.g. arn:aws:lightsail:us-east-1:123456789012:Distribution/<id>) — never the CloudFront ARN.
attachedAtTimestampno

Operation

FieldTypeReqAllowed / constraintsNotes
idStringyesDS2-assigned operation id.
statusOperationStatusyesNotStarted | Started | Failed | Succeeded
isTerminalBooleanyesboolean (true when Failed/Succeeded)true when Failed/Succeeded.
createdAtTimestampno
statusChangedAtTimestampno
operationTypeStringnoCreateSubdomain | UpdateSubdomainAssociation | DeleteSubdomain.
operationDetailsStringnoFor UpdateSubdomainAssociation, carries the action (ASSOCIATE | DISASSOCIATE | TRANSFER); null for Create/Delete.
resourceNameStringnoThe subdomain name the operation acts on (e.g. "app") — NOT the attached resource.
resourceTypeStringnoResource-type token parsed from the Lightsail resourceArn, e.g. DistributionAlways "Subdomain" for these operations.
locationResourceLocationnoSubdomains are global: {regionName:"global", availabilityZone:"all"}.
errorCodeStringnoSet when status=Failed (see Async operation failure codes).
errorDetailsStringnoSet when status=Failed.

ResourceLocation

FieldTypeReqAllowed / constraintsNotes
regionNameStringno"global" for subdomains.
availabilityZoneStringno"all" for subdomains.

DnsRecord

FieldTypeReqAllowed / constraintsNotes
recordTypeDnsRecordTypeyesALIAS_A | ALIAS_AAAA | CNAME | A | AAAAALIAS_A|ALIAS_AAAA|CNAME|A|AAAA.
recordValueStringyes
POST

GetSubdomainAvailability

/subdomain/checkAvailabilitysync200

Checks whether a name is available and optionally places a 15-min exclusive reservation before create. Fully synchronous.

InvalidInput → InvalidInputException · 400BlockedName → InvalidInputException · 400TooManyReservations → OperationFailureException · 400InternalServerError → ServiceException · 500

PAPIS front-door (before the service runs): 401 UnauthenticatedException (not authenticated); 403 AccessDeniedException (not authorized for this operation, or the free-subdomains feature is not enabled); 400 InvalidInputException (called outside us-east-1). See the Model tab.

syncSynchronous response
AvailablehappyMODEL-DERIVEDHTTP 200

Request body

{
  "subdomainName": "app"
}

Response body

{
  "available": true,
  "subdomainName": "app"
}
Available + reservehappyMODEL-DERIVEDHTTP 200

Places a RESERVED hold for 15 minutes; follow with CreateSubdomain to claim it.

Request body

{
  "subdomainName": "app",
  "reserve": true
}

Response body

{
  "available": true,
  "reservationExpiresAt": "2026-08-01T00:15:00Z",
  "subdomainName": "app"
}
Not available (name taken)conflictMODEL-DERIVEDHTTP 200

A taken name returns available=false, not an error.

Request body

{
  "subdomainName": "app"
}

Response body

{
  "available": false,
  "subdomainName": "app"
}
syncSynchronous errors
Invalid name formatvalidationInvalidInputExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "-Bad_Name-"
}

Error response (customer-facing)

{
  "__type": "InvalidInputException",
  "code": "InvalidInput",
  "message": "The specified subdomain name is not valid. It must be 1 to 63 characters using lowercase letters, digits, and hyphens, with no leading or trailing hyphen in any label."
}
Reserved/blocked labelvalidationInvalidInputExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "www"
}

Error response (customer-facing)

{
  "__type": "InvalidInputException",
  "code": "BlockedName",
  "message": "The specified subdomain name uses a reserved label. Please choose a different name and try again."
}
Reservation limit reachedquotaOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "reserve": true
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "TooManyReservations",
  "message": "You have reached the maximum number of subdomain reservations (5). Please try again after a reservation expires or is claimed."
}
Server errorserverServiceExceptionMODEL-DERIVEDHTTP 500

One generic message for every 500 (SubdomainErrors.INTERNAL_ERROR).

Request body

{
  "subdomainName": "app"
}

Error response (customer-facing)

{
  "__type": "ServiceException",
  "message": "Internal Server Error"
}
POST

CreateSubdomain

/subdomain/createasync202

Claims a reserved name, provisions an ACM cert, creates the shadow hosted zone, sets up NS delegation. Returns 202 immediately; poll GetSubdomains for the terminal state.

InvalidInput → InvalidInputException · 400BlockedName → InvalidInputException · 400NameExists → OperationFailureException · 400AlreadyReserved → OperationFailureException · 400DeleteInProgress → OperationFailureException · 400InternalServerError → ServiceException · 500

PAPIS front-door (before the service runs): 401 UnauthenticatedException (not authenticated); 403 AccessDeniedException (not authorized for this operation, or the free-subdomains feature is not enabled); 400 InvalidInputException (called outside us-east-1). See the Model tab.

syncSynchronous response
Accepted (202)happyMODEL-DERIVEDHTTP 202

Immediate acknowledgement. Watch the Asynchronous progression below for the outcome.

Request body

{
  "subdomainName": "app"
}

Response body

{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "PROVISIONING",
    "createdAt": "2026-08-01T00:00:00Z"
  },
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "CreateSubdomain",
    "operationDetails": null,
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
syncSynchronous errors
Name already existsconflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "NameExists",
  "message": "The specified subdomain name already exists. Please choose a different name and try again."
}
Already reserved by callerconflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "AlreadyReserved",
  "message": "The specified subdomain name has already been reserved or created. Please choose a different name and try again."
}
Delete still completingconflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "DeleteInProgress",
  "message": "The subdomain is still being deleted. Please try again in a few moments."
}
Invalid / too deep namevalidationInvalidInputExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "a.b.c.d"
}

Error response (customer-facing)

{
  "__type": "InvalidInputException",
  "code": "InvalidInput",
  "message": "The specified subdomain name has too many labels. A subdomain name can have at most 2 labels."
}
Server errorserverServiceExceptionMODEL-DERIVEDHTTP 500

One generic message for every 500 (SubdomainErrors.INTERNAL_ERROR).

Request body

{
  "subdomainName": "app"
}

Error response (customer-facing)

{
  "__type": "ServiceException",
  "message": "Internal Server Error"
}
asyncAsynchronous progression (poll GetSubdomains)
Success pathProvisioning completes normally.
pollfirst poll (post-202)
PROVISIONING
operation: Started · isTerminal=false
arn is NOT in the GetSubdomains record yet during PROVISIONING — it is returned in the CreateSubdomain 202 (from DS2) and persisted to the record only at provisioning-finalize. Cert + shadow zone + NS delegation in progress.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "PROVISIONING",
    "createdAt": "2026-08-01T00:00:00Z"
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": null,
    "operationDetails": null,
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
poll~seconds later
PROVISIONING
operation: Started · isTerminal=false
Still provisioning; keep polling while isTerminal=false.
pollterminal
UNATTACHED
operation: Succeeded · isTerminal=true
arn persisted; ready to associate.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "UNATTACHED",
    "createdAt": "2026-08-01T00:00:00Z",
    "dnsRecord": {
      "recordType": "ALIAS_A",
      "recordValue": "ns-delegated"
    }
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Succeeded",
    "isTerminal": true,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": null,
    "operationDetails": null,
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
Failure path (rollback)A dependency (ACM/Route53) fails during provisioning.
pollfirst poll (post-202)
PROVISIONING
operation: Started · isTerminal=false
Same PROVISIONING view as the success path (no arn in GetSubdomains yet).
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "PROVISIONING",
    "createdAt": "2026-08-01T00:00:00Z"
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": null,
    "operationDetails": null,
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
pollterminal
(removed)
operation: Failed · isTerminal=true
Rollback deletes the PROVISIONING row. GetSubdomains(name) now 404s; the operation (id from the 202) reports Failed with errorDetails.
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Failed",
    "isTerminal": true,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "CreateSubdomain",
    "operationDetails": null,
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": "CreateFailed",
    "errorDetails": "The operation could not be completed. Please try again later."
  }
}
POST

Associate

/subdomain/updateAssociationasync202

UpdateSubdomainAssociation with action=ASSOCIATE. Attaches an UNATTACHED subdomain to a Lightsail resource (requires targetResourceArn). Returns 202; poll GetSubdomains. On async failure the subdomain reverts to UNATTACHED.

InvalidInput → InvalidInputException · 400AccessDenied → AccessDeniedException · 403StateConflict → OperationFailureException · 400ResourceAlreadyInUse → OperationFailureException · 400ResourceAlreadyAttached → OperationFailureException · 400UpdateConflict → OperationFailureException · 400SubdomainNotFound → NotFoundException · 404InternalServerError → ServiceException · 500

PAPIS front-door (before the service runs): 401 UnauthenticatedException (not authenticated); 403 AccessDeniedException (not authorized for this operation, or the free-subdomains feature is not enabled); 403 AccessDeniedException (dependent-action IAM on the target distribution); 400 InvalidInputException (called outside us-east-1). See the Model tab.

syncSynchronous response
Accepted (202)happyMODEL-DERIVEDHTTP 202

Request body

{
  "subdomainName": "app",
  "action": "ASSOCIATE",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333"
}

Response body

{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "ATTACHING",
    "createdAt": "2026-08-01T00:00:00Z"
  },
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "ASSOCIATE",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
syncSynchronous errors
Not UNATTACHEDconflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "action": "ASSOCIATE",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "StateConflict",
  "message": "The subdomain must be in the UNATTACHED state to associate a resource, but it is currently ATTACHED."
}
Target already in useconflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "action": "ASSOCIATE",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "ResourceAlreadyInUse",
  "message": "The specified resource is already attached to subdomain other.amazonlightsail.com. Please detach it first or choose a different resource."
}
Already attached to targetconflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "action": "ASSOCIATE",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "ResourceAlreadyAttached",
  "message": "The subdomain is already associated with resource my-distribution."
}
Invalid target resource ARNvalidationInvalidInputExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "action": "ASSOCIATE"
}

Error response (customer-facing)

{
  "__type": "InvalidInputException",
  "code": "InvalidInput",
  "message": "The specified target resource ARN is not valid."
}
Unsupported target typevalidationInvalidInputExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "action": "ASSOCIATE",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Instance/inst-1"
}

Error response (customer-facing)

{
  "__type": "InvalidInputException",
  "code": "UnsupportedType",
  "message": "The specified resource arn:aws:lightsail:us-east-1:123456789012:Instance/inst-1 is not a supported attachable resource type."
}
Dependent-auth denied (attach)authAccessDeniedExceptionMODEL-DERIVEDHTTP 403

PAPIS front-door (before the service runs): the caller's IAM policy must allow lightsail:AttachCertificateToDistribution on the target distribution, including any aws:ResourceTag conditions.

Request body

{
  "subdomainName": "app",
  "action": "ASSOCIATE",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/0000dead-beef-4000-8000-000000000000"
}

Error response (customer-facing)

{
  "__type": "AccessDeniedException",
  "message": "You are not authorized to perform: lightsail:AttachCertificateToDistribution on the specified resource."
}
Subdomain not foundnotfoundNotFoundExceptionMODEL-DERIVEDHTTP 404

Request body

{
  "subdomainName": "nope",
  "action": "ASSOCIATE",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333"
}

Error response (customer-facing)

{
  "__type": "NotFoundException",
  "code": "SubdomainNotFound",
  "message": "The specified subdomain could not be found."
}
asyncAsynchronous progression (poll GetSubdomains)
Success pathAlias record written + source resource updated.
t0202 response
ATTACHING
operation: Started · isTerminal=false
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "ATTACHING",
    "createdAt": "2026-08-01T00:00:00Z"
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "ASSOCIATE",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
pollterminal
ATTACHED
operation: Succeeded · isTerminal=true
attachedResource populated.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "ATTACHED",
    "createdAt": "2026-08-01T00:00:00Z",
    "attachedResource": {
      "resourceName": "my-distribution",
      "resourceType": "Distribution",
      "region": "us-east-1",
      "resourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333"
    }
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Succeeded",
    "isTerminal": true,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "ASSOCIATE",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
Failure path (revert)Alias write / source-resource callback fails.
t0202 response
ATTACHING
operation: Started · isTerminal=false
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "ATTACHING",
    "createdAt": "2026-08-01T00:00:00Z"
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "ASSOCIATE",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
pollterminal
UNATTACHED
operation: Failed · isTerminal=true
Reverts to the prior stable state; operation Failed.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "UNATTACHED",
    "createdAt": "2026-08-01T00:00:00Z"
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Failed",
    "isTerminal": true,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "ASSOCIATE",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": "UpdateFailed",
    "errorDetails": "The operation could not be completed. Please try again later."
  }
}
POST

Disassociate

/subdomain/updateAssociationasync202

UpdateSubdomainAssociation with action=DISASSOCIATE. Detaches an ATTACHED subdomain (no resourceName needed — the source is read from our datastore). Returns 202; poll GetSubdomains. On async failure the subdomain reverts to ATTACHED.

InvalidInput → InvalidInputException · 400AccessDenied → AccessDeniedException · 403StateConflict → OperationFailureException · 400UpdateConflict → OperationFailureException · 400SubdomainNotFound → NotFoundException · 404InternalServerError → ServiceException · 500

PAPIS front-door (before the service runs): 401 UnauthenticatedException (not authenticated); 403 AccessDeniedException (not authorized for this operation, or the free-subdomains feature is not enabled); 403 AccessDeniedException (dependent-action IAM on the target distribution); 400 InvalidInputException (called outside us-east-1). See the Model tab.

syncSynchronous response
Accepted (202)happyMODEL-DERIVEDHTTP 202

Request body

{
  "subdomainName": "app",
  "action": "DISASSOCIATE"
}

Response body

{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "DETACHING",
    "createdAt": "2026-08-01T00:00:00Z"
  },
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "DISASSOCIATE",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
syncSynchronous errors
Not ATTACHEDconflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "action": "DISASSOCIATE"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "StateConflict",
  "message": "The subdomain must be in the ATTACHED state to DISASSOCIATE, but it is currently UNATTACHED."
}
Dependent-auth denied (detach)authAccessDeniedExceptionMODEL-DERIVEDHTTP 403

PAPIS front-door: the caller's IAM policy must allow lightsail:DetachCertificateFromDistribution on the currently-attached distribution (resolved from the subdomain's record). Thrown before the service runs.

Request body

{
  "subdomainName": "app",
  "action": "DISASSOCIATE"
}

Error response (customer-facing)

{
  "__type": "AccessDeniedException",
  "message": "You are not authorized to perform: lightsail:DetachCertificateFromDistribution on the specified resource."
}
Subdomain not foundnotfoundNotFoundExceptionMODEL-DERIVEDHTTP 404

Request body

{
  "subdomainName": "nope",
  "action": "DISASSOCIATE"
}

Error response (customer-facing)

{
  "__type": "NotFoundException",
  "code": "SubdomainNotFound",
  "message": "The specified subdomain could not be found."
}
Concurrent updateconflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "action": "DISASSOCIATE"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "UpdateConflict",
  "message": "The subdomain was modified by another request. Please retrieve the latest state and try again."
}
asyncAsynchronous progression (poll GetSubdomains)
Success pathAlias removed + source resource notified.
t0202 response
DETACHING
operation: Started · isTerminal=false
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "DETACHING",
    "createdAt": "2026-08-01T00:00:00Z",
    "attachedResource": {
      "resourceName": "my-distribution",
      "resourceType": "Distribution",
      "region": "us-east-1",
      "resourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333"
    }
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "DISASSOCIATE",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
pollterminal
UNATTACHED
operation: Succeeded · isTerminal=true
attachedResource cleared.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "UNATTACHED",
    "createdAt": "2026-08-01T00:00:00Z"
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Succeeded",
    "isTerminal": true,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "DISASSOCIATE",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
Failure path (revert)Detach callback fails.
t0202 response
DETACHING
operation: Started · isTerminal=false
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "DETACHING",
    "createdAt": "2026-08-01T00:00:00Z",
    "attachedResource": {
      "resourceName": "my-distribution",
      "resourceType": "Distribution",
      "region": "us-east-1",
      "resourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333"
    }
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "DISASSOCIATE",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
pollterminal
ATTACHED
operation: Failed · isTerminal=true
Reverts to ATTACHED; operation Failed.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "ATTACHED",
    "createdAt": "2026-08-01T00:00:00Z",
    "attachedResource": {
      "resourceName": "my-distribution",
      "resourceType": "Distribution",
      "region": "us-east-1",
      "resourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333"
    }
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Failed",
    "isTerminal": true,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "DISASSOCIATE",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": "UpdateFailed",
    "errorDetails": "The operation could not be completed. Please try again later."
  }
}
POST

Transfer

/subdomain/updateAssociationasync202

UpdateSubdomainAssociation with action=TRANSFER. Moves an ATTACHED subdomain from its current resource to a new one (requires targetResourceArn). Returns 202; poll GetSubdomains. On async failure the subdomain reverts to the ORIGINAL resource.

InvalidInput → InvalidInputException · 400AccessDenied → AccessDeniedException · 403StateConflict → OperationFailureException · 400ResourceAlreadyInUse → OperationFailureException · 400UpdateConflict → OperationFailureException · 400SubdomainNotFound → NotFoundException · 404InternalServerError → ServiceException · 500

PAPIS front-door (before the service runs): 401 UnauthenticatedException (not authenticated); 403 AccessDeniedException (not authorized for this operation, or the free-subdomains feature is not enabled); 403 AccessDeniedException (dependent-action IAM on the target distribution); 400 InvalidInputException (called outside us-east-1). See the Model tab.

syncSynchronous response
Accepted (202)happyMODEL-DERIVEDHTTP 202

Request body

{
  "subdomainName": "app",
  "action": "TRANSFER",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/9f8e7d6c-5b4a-3210-fedc-999988887777"
}

Response body

{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "TRANSFERRING",
    "createdAt": "2026-08-01T00:00:00Z"
  },
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "TRANSFER",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
syncSynchronous errors
Not ATTACHEDconflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "action": "TRANSFER",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/9f8e7d6c-5b4a-3210-fedc-999988887777"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "StateConflict",
  "message": "The subdomain must be in the ATTACHED state to TRANSFER, but it is currently UNATTACHED."
}
Target already in useconflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "action": "TRANSFER",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/9f8e7d6c-5b4a-3210-fedc-999988887777"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "ResourceAlreadyInUse",
  "message": "The specified resource is already attached to subdomain other.amazonlightsail.com. Please detach it first or choose a different resource."
}
Invalid target resource ARNvalidationInvalidInputExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "action": "TRANSFER"
}

Error response (customer-facing)

{
  "__type": "InvalidInputException",
  "code": "InvalidInput",
  "message": "The specified target resource ARN is not valid."
}
Unsupported target typevalidationInvalidInputExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "action": "TRANSFER",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Instance/inst-1"
}

Error response (customer-facing)

{
  "__type": "InvalidInputException",
  "code": "UnsupportedType",
  "message": "The specified resource arn:aws:lightsail:us-east-1:123456789012:Instance/inst-1 is not a supported attachable resource type."
}
Dependent-auth deniedauthAccessDeniedExceptionMODEL-DERIVEDHTTP 403

PAPIS front-door: TRANSFER requires lightsail:AttachCertificateToDistribution on the NEW distribution AND lightsail:DetachCertificateFromDistribution on the currently-attached one. Thrown before the service runs.

Request body

{
  "subdomainName": "app",
  "action": "TRANSFER",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/0000dead-beef-4000-8000-000000000000"
}

Error response (customer-facing)

{
  "__type": "AccessDeniedException",
  "message": "You are not authorized to perform: lightsail:AttachCertificateToDistribution on the specified resource."
}
Subdomain not foundnotfoundNotFoundExceptionMODEL-DERIVEDHTTP 404

Request body

{
  "subdomainName": "nope",
  "action": "TRANSFER",
  "targetResourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/9f8e7d6c-5b4a-3210-fedc-999988887777"
}

Error response (customer-facing)

{
  "__type": "NotFoundException",
  "code": "SubdomainNotFound",
  "message": "The specified subdomain could not be found."
}
asyncAsynchronous progression (poll GetSubdomains)
Success pathDetach old + attach new complete.
t0202 response
TRANSFERRING
operation: Started · isTerminal=false
Currently attached to the old resource.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "TRANSFERRING",
    "createdAt": "2026-08-01T00:00:00Z",
    "attachedResource": {
      "resourceName": "my-distribution",
      "resourceType": "Distribution",
      "region": "us-east-1",
      "resourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333"
    }
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "TRANSFER",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
pollterminal
ATTACHED
operation: Succeeded · isTerminal=true
attachedResource now points at the new resource.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "ATTACHED",
    "createdAt": "2026-08-01T00:00:00Z",
    "attachedResource": {
      "resourceName": "new-distribution",
      "resourceType": "Distribution",
      "region": "us-east-1",
      "resourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/9f8e7d6c-5b4a-3210-fedc-999988887777"
    }
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Succeeded",
    "isTerminal": true,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "TRANSFER",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
Failure path (revert)Attach-to-new fails after detach.
t0202 response
TRANSFERRING
operation: Started · isTerminal=false
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "TRANSFERRING",
    "createdAt": "2026-08-01T00:00:00Z",
    "attachedResource": {
      "resourceName": "my-distribution",
      "resourceType": "Distribution",
      "region": "us-east-1",
      "resourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333"
    }
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "TRANSFER",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
pollterminal
ATTACHED
operation: Failed · isTerminal=true
Reverts to the ORIGINAL resource; operation Failed.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "ATTACHED",
    "createdAt": "2026-08-01T00:00:00Z",
    "attachedResource": {
      "resourceName": "my-distribution",
      "resourceType": "Distribution",
      "region": "us-east-1",
      "resourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333"
    }
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Failed",
    "isTerminal": true,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "UpdateSubdomainAssociation",
    "operationDetails": "TRANSFER",
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": "UpdateFailed",
    "errorDetails": "The operation could not be completed. Please try again later."
  }
}
POST

DeleteSubdomain

/subdomain/deleteasync202

Releases a name and places it in cooldown. NS delegation is removed immediately to prevent takeover. Returns 202; poll GetSubdomains for the terminal state.

InvalidInput → InvalidInputException · 400SubdomainAttached → OperationFailureException · 400SubdomainProvisioning → OperationFailureException · 400SubdomainInCooldown → OperationFailureException · 400DeleteConflict → OperationFailureException · 400SubdomainNotFound → NotFoundException · 404InternalServerError → ServiceException · 500

PAPIS front-door (before the service runs): 401 UnauthenticatedException (not authenticated); 403 AccessDeniedException (not authorized for this operation, or the free-subdomains feature is not enabled); 400 InvalidInputException (called outside us-east-1). See the Model tab.

syncSynchronous response
Accepted (202)happyMODEL-DERIVEDHTTP 202

Request body

{
  "subdomainName": "app"
}

Response body

{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "DELETED",
    "createdAt": "2026-08-01T00:00:00Z"
  },
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "DeleteSubdomain",
    "operationDetails": null,
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
syncSynchronous errors
Attached — disassociate firstconflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "SubdomainAttached",
  "message": "The subdomain is attached to a resource. Please disassociate it before deleting."
}
Still provisioningconflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "SubdomainProvisioning",
  "message": "The subdomain is still provisioning. Please try again once provisioning completes."
}
Already deleted (cooldown)conflictOperationFailureExceptionMODEL-DERIVEDHTTP 400

Distinct 409 (not a 404) so the UI can explain the cooldown.

Request body

{
  "subdomainName": "app"
}

Error response (customer-facing)

{
  "__type": "OperationFailureException",
  "code": "SubdomainInCooldown",
  "message": "The subdomain has already been deleted and is in its reclaim cooldown. It cannot be deleted again."
}
Subdomain not foundnotfoundNotFoundExceptionMODEL-DERIVEDHTTP 404

Request body

{
  "subdomainName": "nope"
}

Error response (customer-facing)

{
  "__type": "NotFoundException",
  "code": "SubdomainNotFound",
  "message": "The specified subdomain could not be found."
}
Server errorserverServiceExceptionMODEL-DERIVEDHTTP 500

One generic message for every 500 (SubdomainErrors.INTERNAL_ERROR).

Request body

{
  "subdomainName": "app"
}

Error response (customer-facing)

{
  "__type": "ServiceException",
  "message": "Internal Server Error"
}
asyncAsynchronous progression (poll GetSubdomains)
Leaf delete → cooldown → removedAn UNATTACHED subdomain with no children.
t0202 response
DELETED
operation: Started · isTerminal=false
NS delegation removed immediately.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "DELETED",
    "createdAt": "2026-08-01T00:00:00Z"
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": null,
    "operationDetails": null,
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
pollterminal
DELETED
operation: Succeeded · isTerminal=true
In reclaim cooldown; still listed (list mode) with state DELETED.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "DELETED",
    "createdAt": "2026-08-01T00:00:00Z"
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Succeeded",
    "isTerminal": true,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": null,
    "operationDetails": null,
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
laterafter cooldown
(removed)
operation: Succeeded · isTerminal=true
No longer returned by GetSubdomains; name reclaimable.
Level-1 with children → IMPLICITA level-1 subdomain whose children must keep resolving.
t0202 response
DELETED
operation: Started · isTerminal=false
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "DELETED",
    "createdAt": "2026-08-01T00:00:00Z"
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": null,
    "operationDetails": null,
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
pollterminal
IMPLICIT
operation: Succeeded · isTerminal=true
Demoted to a structural parent (no cert/resource); arn is cleared. Children delegate directly from the apex, so they are unaffected.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "IMPLICIT",
    "createdAt": "2026-08-01T00:00:00Z"
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Succeeded",
    "isTerminal": true,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": null,
    "operationDetails": null,
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
Failure path (revert)Teardown fails after the tombstone is written.
t0202 response
DELETED
operation: Started · isTerminal=false
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "DELETED",
    "createdAt": "2026-08-01T00:00:00Z"
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": null,
    "operationDetails": null,
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
pollterminal
UNATTACHED
operation: Failed · isTerminal=true
Reverts to the prior stable state; operation Failed.
GetSubdomains →
{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "UNATTACHED",
    "createdAt": "2026-08-01T00:00:00Z"
  }
}
GetOperation →
{
  "operation": {
    "id": "op-83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "status": "Failed",
    "isTerminal": true,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "DeleteSubdomain",
    "operationDetails": null,
    "resourceName": "app",
    "resourceType": "Subdomain",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": "DeleteFailed",
    "errorDetails": "The operation could not be completed. Please try again later."
  }
}
POST

GetSubdomains

/subdomain/getsync200

Returns a single subdomain (by name) or the caller's full hierarchy (list mode, paginated by root subtree). This is the poll target for every async operation above.

InvalidInput → InvalidInputException · 400SubdomainNotFound → NotFoundException · 404InternalServerError → ServiceException · 500

PAPIS front-door (before the service runs): 401 UnauthenticatedException (not authenticated); 403 AccessDeniedException (not authorized for this operation, or the free-subdomains feature is not enabled); 400 InvalidInputException (called outside us-east-1). See the Model tab.

syncSynchronous response
Single lookup — foundhappyMODEL-DERIVEDHTTP 200

Request body

{
  "subdomainName": "app"
}

Response body

{
  "subdomain": {
    "subdomainName": "app",
    "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
    "fqdn": "app.amazonlightsail.com",
    "depth": 1,
    "state": "ATTACHED",
    "createdAt": "2026-08-01T00:00:00Z",
    "attachedResource": {
      "resourceName": "my-distribution",
      "resourceType": "Distribution",
      "region": "us-east-1",
      "resourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/1a2b3c4d-5e6f-7a8b-9c0d-111122223333",
      "attachedAt": "2026-08-01T00:05:00Z"
    },
    "dnsRecord": {
      "recordType": "ALIAS_A",
      "recordValue": "d123.cloudfront.net"
    }
  }
}
List mode — hierarchy + paginghappyMODEL-DERIVEDHTTP 200

Each node (roots and children) is the FULL SubdomainSummary — identical shape to single-get. List reads the ownerAccountId-createdAt-index GSI (projection ALL), so no fields are trimmed.

Request body

{}

Response body

{
  "subdomains": [
    {
      "subdomainName": "app",
      "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/83e5fe9b-1c2d-4e5f-9a0b-1234567890ab",
      "fqdn": "app.amazonlightsail.com",
      "depth": 1,
      "state": "UNATTACHED",
      "createdAt": "2026-08-01T00:00:00Z",
      "children": [
        {
          "subdomainName": "api.app",
          "arn": "arn:aws:lightsail:us-east-1:123456789012:Subdomain/9f2c7b4a-0d1e-4f6a-8b2c-abcdef012345",
          "fqdn": "api.app.amazonlightsail.com",
          "depth": 2,
          "state": "ATTACHED",
          "parentFqdn": "app.amazonlightsail.com",
          "createdAt": "2026-08-01T00:02:00Z",
          "attachedResource": {
            "resourceName": "api-distribution",
            "resourceType": "Distribution",
            "region": "us-east-1",
            "resourceArn": "arn:aws:lightsail:us-east-1:123456789012:Distribution/2b3c4d5e-6f70-8192-a3b4-444455556666",
            "attachedAt": "2026-08-01T00:05:00Z"
          },
          "dnsRecord": {
            "recordType": "ALIAS_A",
            "recordValue": "d456.cloudfront.net"
          }
        }
      ]
    }
  ],
  "nextPageToken": "eyJyb290IjoiYXBwMiJ9"
}
Empty listhappyMODEL-DERIVEDHTTP 200

Request body

{}

Response body

{
  "subdomains": []
}
syncSynchronous errors
Single lookup — not foundnotfoundNotFoundExceptionMODEL-DERIVEDHTTP 404

Request body

{
  "subdomainName": "nope"
}

Error response (customer-facing)

{
  "__type": "NotFoundException",
  "code": "SubdomainNotFound",
  "message": "The specified subdomain could not be found."
}
name + pageToken togethervalidationInvalidInputExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "subdomainName": "app",
  "pageToken": "eyJ..."
}

Error response (customer-facing)

{
  "__type": "InvalidInputException",
  "code": "InvalidInput",
  "message": "A subdomain name and a page token cannot be provided in the same request. Please provide only one and try again."
}
Invalid pageTokenvalidationInvalidInputExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "pageToken": "garbage"
}

Error response (customer-facing)

{
  "__type": "InvalidInputException",
  "code": "InvalidInput",
  "message": "The specified page token is not valid. Please use the nextPageToken from a previous response and try again."
}
POST

CreateDistribution (CDN)

/CreateDistribution (ParksideCloudFrontService)async202

CreateDistribution with a subdomainName atomically creates the CDN distribution AND creates + associates a free subdomain to it. Returns 202; the distribution comes back with a subdomain block { fqdn, state, errorMessage } whose state you poll via GetDistributions. Only the subdomain-relevant surface is documented here — the full LightsailDistribution (origin, cacheBehaviors, bundleId, status, …) is out of scope. Required inputs: distributionName, origin, defaultCacheBehavior, bundleId; subdomainName is optional and feature-gated. Distribution-subdomain state: Creating → Attaching → Attached (or Error). Track it via GetDistributions — the subdomain attach is NOT tracked by the returned operation (that operation is for the distribution). Note: the model enum also defines Created, but the service does not currently emit it (the internal Provisioning phase is surfaced as Creating).

InvalidInput → InvalidInputException · 400AccessDenied → AccessDeniedException · 403

PAPIS front-door (before the service runs): 401 UnauthenticatedException (not authenticated); 403 AccessDeniedException (not authorized for this operation, or the free-subdomains feature is not enabled); 400 InvalidInputException (called outside us-east-1). See the Model tab.

syncSynchronous response
Accepted (202)happyMODEL-DERIVEDHTTP 202

subdomainName is optional and gated by the free-subdomains feature. The distribution.subdomain block is set synchronously to state=Creating; poll GetDistributions for its progression. The returned operation tracks the DISTRIBUTION creation (not the subdomain attach). Non-subdomain distribution fields are omitted here.

Request body

{
  "distributionName": "my-distribution",
  "origin": {
    "name": "my-instance",
    "regionName": "us-east-1",
    "protocolPolicy": "http-only"
  },
  "bundleId": "small_1_0",
  "subdomainName": "app"
}

Response body

{
  "distribution": {
    "name": "my-distribution",
    "subdomain": {
      "fqdn": "app.amazonlightsail.com",
      "state": "Creating",
      "errorMessage": null
    }
  },
  "operation": {
    "id": "op-cdn-1a2b3c4d-5e6f",
    "status": "Started",
    "isTerminal": false,
    "createdAt": "2026-08-01T00:00:00Z",
    "statusChangedAt": "2026-08-01T00:00:05Z",
    "operationType": "CreateDistribution",
    "operationDetails": null,
    "resourceName": "my-distribution",
    "resourceType": "Distribution",
    "location": {
      "availabilityZone": "all",
      "regionName": "global"
    },
    "errorCode": null,
    "errorDetails": null
  }
}
syncSynchronous errors
Invalid subdomainNamevalidationInvalidInputExceptionMODEL-DERIVEDHTTP 400

Request body

{
  "distributionName": "my-distribution",
  "subdomainName": "-bad-"
}

Error response (customer-facing)

{
  "__type": "InvalidInputException",
  "code": "InvalidInput",
  "message": "The specified subdomain name is not valid. It must be 1 to 63 characters using lowercase letters, digits, and hyphens, with no leading or trailing hyphen in any label."
}
Feature not enabledauthAccessDeniedExceptionMODEL-DERIVEDHTTP 403

subdomainName was supplied but the free-subdomains feature (subdomain_fac) is not enabled for the account. CreateDistribution WITHOUT subdomainName is unaffected (GA).

Request body

{
  "distributionName": "my-distribution",
  "subdomainName": "app"
}

Error response (customer-facing)

{
  "__type": "AccessDeniedException",
  "message": "Sorry, you are not authorized to perform the request."
}
Dependent-auth deniedauthAccessDeniedExceptionMODEL-DERIVEDHTTP 403

Create-with-subdomain requires the caller be authorized for lightsail:CreateSubdomain AND lightsail:UpdateSubdomainAssociation (on the Subdomain) AND lightsail:AttachCertificateToDistribution (on the Distribution). The targets don't exist yet, so authorization is against resource-type wildcards. PAPIS front-door.

Request body

{
  "distributionName": "my-distribution",
  "subdomainName": "app"
}

Error response (customer-facing)

{
  "__type": "AccessDeniedException",
  "message": "You are not authorized to perform: lightsail:CreateSubdomain on the specified resource."
}
asyncAsynchronous progression (poll GetSubdomains)
Success pathThe free subdomain is claimed, associated, and the attach is confirmed. Poll GetDistributions → distribution.subdomain.state.
t0202 response
Creating
distribution.subdomain.state set synchronously (internally the name is claimed + provisioned; both surface as Creating).
GetDistributions →
{
  "distribution": {
    "name": "my-distribution",
    "subdomain": {
      "fqdn": "app.amazonlightsail.com",
      "state": "Creating",
      "errorMessage": null
    }
  }
}
pollGetDistributions
Attaching
Name is UNATTACHED; the associate/attach workflow is in flight.
GetDistributions →
{
  "distribution": {
    "name": "my-distribution",
    "subdomain": {
      "fqdn": "app.amazonlightsail.com",
      "state": "Attaching",
      "errorMessage": null
    }
  }
}
pollterminal
Attached
Attach confirmed by the AttachCertificateToDistribution callback; fqdn is live on the distribution.
GetDistributions →
{
  "distribution": {
    "name": "my-distribution",
    "subdomain": {
      "fqdn": "app.amazonlightsail.com",
      "state": "Attached",
      "errorMessage": null
    }
  }
}
Failure pathSubdomain create, associate, or attach fails (or times out). Can occur from Creating or Attaching.
t0202 response
Creating
GetDistributions →
{
  "distribution": {
    "name": "my-distribution",
    "subdomain": {
      "fqdn": "app.amazonlightsail.com",
      "state": "Creating",
      "errorMessage": null
    }
  }
}
pollterminal
Error
distribution.subdomain.state=Error with a generic customer-safe errorMessage. The distribution itself is still created — only the subdomain attach failed.
GetDistributions →
{
  "distribution": {
    "name": "my-distribution",
    "subdomain": {
      "fqdn": "app.amazonlightsail.com",
      "state": "Error",
      "errorMessage": "We were unable to attach the subdomain. Please try again later."
    }
  }
}