{
  "openapi": "3.1.0",
  "info": {
    "title": "Spaces Embed Service APIs",
    "description": "OpenAPI v3 specification for `spaces-embed-service` - the Backend For Frontend (BFF) for the embedded Spaces experience (Auth0 launch-token exchange, session management, and reverse proxying to Catalog).\n\nThe endpoints below are grouped by tag:\n\n- **Partners**: OEM partner onboarding and management\n- **Embed launch**: The iframe entry point\n- **Embed session**: Session identity and lifecycle for the consumer UI\n- **Health**: Service liveness and readiness checks\n\n**Prerequisites**\n\n1. For `/v1/partners/**`: a Boomi-internal JWT already carrying the BOOMI_INTERNAL authority, issued out-of-band by Boomi's internal auth — this API does not mint that token itself.\n2. For the embed group (`/embed`, `/embed-auth/**`, `/logout`): an Auth0-issued launch `id_token`, for a partner/tenant already registered with a reachable JWKS endpoint in this service's tenant configuration, obtained by starting a real launch flow — `GET /embed?token=...` — from a browser rather than Swagger's Try-it-out.\n\n**Authentication** — two independent models are in play across this service:\n\n1. `/v1/partners/**` — Boomi-internal JWT bearer token (BOOMI_INTERNAL authority). Click **Authorize** below to supply it.\n2. `/embed, /embed-auth/**, /logout` — a server-managed, httpOnly, SameSite=None session cookie minted by `GET /embed`. There is no bearer credential to enter here; these are documented for reference but are best exercised from a real browser session rather than Swagger's Try-it-out.\n\n**Required privileges**\n\n1. `/v1/partners/**` requires the BOOMI_INTERNAL authority on the bearer token, enforced before the request reaches the controller — a token without it is rejected with 401 (empty body).\n2. The embed/session group has no separate privilege beyond holding a valid, unexpired session; any caller who completed the `/embed` launch flow may call `/embed-auth/**` and `/logout` for that session.\n\n**Base URL** — this service is deployed per environment (local, sandbox, QA, ProdClone, Production, and more); pick the environment you're targeting from the **Servers** dropdown above rather than assuming a fixed URL — it is populated automatically with this deployment's own public URL.\n\n**Request and response format**\n\n1. Bodies are JSON unless an operation's own documentation says otherwise (e.g. `GET /v1/partners/jwt-platform-token` returns a plain-text redirect URL, and `GET /embed` issues a 302 redirect with no body).\n2. Paged list endpoints (e.g. `GET /v1/partners`) wrap results in the `PageResponse` schema: `{content, page, size, totalElements, totalPages}`.\n3. Error bodies use the shared `ErrorResponse` schema: `{errors: [{field, code, message}]}` — one entry per validation/business-rule failure. (A couple of operations document a narrower, ad-hoc shape instead; see that operation's own responses.)\n\n**Error codes** — standard HTTP status codes are used throughout this API (400, 401, 403, 404, 409, 422, 500 and 503 all appear somewhere); see each operation's own **Responses** list below for exactly which codes it can return and what each one means.\n\n**API usage limits** — no application-level rate limiting (per-account or otherwise) is currently enforced by this service.",
    "contact": {
      "name": "Customer Support",
      "url": "https://community.boomi.com/s/support",
      "email": "support@boomi.com"
    },
    "license": {
      "name": "Copyright © 2026 Boomi, LP."
    },
    "version": "1.0.8"
  },
  "servers": [
    {
      "url": "https://spaces-embed-service.boomi.com",
      "description": "US Platform"
    },
    {
      "url": "https://spaces-embed-service.gb.boomi.com",
      "description": "UK Platform"
    }
  ],
  "security": [
    {
      "BoomiJwtBearer": []
    }
  ],
  "tags": [
    {
      "name": "Embed launch",
      "description": "Entry point for the embedded Spaces iframe: verifies the Auth0 launch token, creates a server-side session, and redirects into the embedded app."
    },
    {
      "name": "Health",
      "description": "Liveness check consumed by the Application Load Balancer (ALB) target group and Kubernetes probes."
    },
    {
      "name": "Partners",
      "description": "OEM partner onboarding and management. Every endpoint requires a Boomi-internal JWT bearer token with the BOOMI_INTERNAL authority."
    },
    {
      "name": "Embed session",
      "description": "Session identity + lifecycle for the embedded consumer UI. /embed-auth/** requires an active session (a server-managed httpOnly cookie, enforced by SessionFilter before the controller runs); /logout is public."
    }
  ],
  "paths": {
    "/v1/partners/{partnerId}": {
      "get": {
        "tags": [
          "Partners"
        ],
        "summary": "Get a partner by uid",
        "description": "Direct lookup by uid; returns the details of the partner, including the partner name, account ID, child account details, and the partner's associated domains.",
        "operationId": "getPartnerById",
        "parameters": [
          {
            "name": "partnerId",
            "in": "path",
            "description": "The partner's unique identifier (uid), generated server-side and returned as the uid field in the list, create, and update partner responses; pass it here to identify which partner this request applies to.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "404": {
            "description": "No partner exists with this uid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "field": "tenantId",
                      "code": "PARTNER_NOT_FOUND",
                      "message": "Partner not found: 8f14e45f-ceea-467e-b7a9-53f68b6bab63"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid Boomi JWT bearer token. Empty body.",
            "content": {
              "application/json": {

              }
            }
          },
          "200": {
            "description": "Partner found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Partner"
                }
              }
            }
          }
        },
        "security": [
          {
            "BoomiJwtBearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "Partners"
        ],
        "summary": "Replace a partner's configuration",
        "description": "Fully replaces all fields for an existing partner, applying the same uniqueness and existence checks as the creation endpoint.\u003Cbr\u003E\u003Cbr\u003E\u003Cb\u003EKnown behavior:\u003C/b\u003E similar to partner creation, validation failures, ACCOUNT_NOT_FOUND, and duplicate-field conflicts currently return an HTTP \u003Cb\u003E500\u003C/b\u003E response (rather than 422 Unprocessable Entity or 409 Conflict).",
        "operationId": "updatePartner",
        "parameters": [
          {
            "name": "partnerId",
            "in": "path",
            "description": "The partner's unique identifier (uid), generated server-side and returned as the uid field in the list, create, and update partner responses; pass it here to identify which partner this request applies to.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "500": {
            "description": "One or more validation/business-rule failures (see POST /v1/partners for the same examples: missing fields, invalid format, ACCOUNT_NOT_FOUND, duplicate-field conflicts).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "Invalid domainName format": {
                    "value": {
                      "errors": [
                        {
                          "field": "domainName",
                          "code": "INVALID_DOMAIN",
                          "message": "domainName must be a valid hostname ending with .com (no scheme, letters/digits/hyphens/dots)"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "200": {
            "description": "Partner updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Partner"
                }
              }
            }
          },
          "404": {
            "description": "No partner exists with this uid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "field": "tenantId",
                      "code": "PARTNER_NOT_FOUND",
                      "message": "Partner not found: 8f14e45f-ceea-467e-b7a9-53f68b6bab63"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid Boomi JWT bearer token. Empty body.",
            "content": {
              "application/json": {

              }
            }
          }
        },
        "security": [
          {
            "BoomiJwtBearer": []
          }
        ]
      },
      "patch": {
        "tags": [
          "Partners"
        ],
        "summary": "Partially update a partner",
        "description": "Only fields present in the payload are validated and applied; omitted fields are left untouched.",
        "operationId": "partialUpdate",
        "parameters": [
          {
            "name": "partnerId",
            "in": "path",
            "description": "The partner's unique identifier (uid), generated server-side and returned as the uid field in the list, create, and update partner responses; pass it here to identify which partner this request applies to.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerPatchRequest"
              },
              "examples": {
                "Update childDetails only": {
                  "description": "Update childDetails only",
                  "value": {
                    "childDetails": [
                      {
                        "childAccountId": "acme-child-001",
                        "childEmail": "user@acme.com"
                      }
                    ]
                  }
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "409": {
            "description": "A childDetails entry's childAccountId is already registered with a different childEmail than the one requested.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "field": "childDetails",
                      "code": "CHILD_EMAIL_MISMATCH",
                      "message": "childAccountId 'acme-child-001' is already registered with childEmail 'old@acme.com' and cannot be changed to 'new@acme.com'"
                    }
                  ]
                }
              }
            }
          },
          "200": {
            "description": "Partner updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Partner"
                }
              }
            }
          },
          "404": {
            "description": "No partner exists with this uid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "field": "tenantId",
                      "code": "PARTNER_NOT_FOUND",
                      "message": "Partner not found: 8f14e45f-ceea-467e-b7a9-53f68b6bab63"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Bean-validation failure on a provided field, or a childDetails entry references an unknown childAccountId.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "Invalid iframeUrl format": {
                    "value": {
                      "errors": [
                        {
                          "field": "iframeUrl",
                          "code": "INVALID_IFRAME_URL",
                          "message": "iframeUrl must be a valid HTTP or HTTPS URL"
                        }
                      ]
                    }
                  },
                  "Unknown childAccountId": {
                    "value": {
                      "errors": [
                        {
                          "field": "childDetails",
                          "code": "CHILD_ACCOUNT_ID_NOT_FOUND",
                          "message": "childAccountId 'acme-child-001' is not a valid account"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid Boomi JWT bearer token. Empty body.",
            "content": {
              "application/json": {

              }
            }
          }
        },
        "security": [
          {
            "BoomiJwtBearer": []
          }
        ]
      }
    },
    "/v1/partners/migrate-domains": {
      "put": {
        "tags": [
          "Partners"
        ],
        "summary": "Backfill domains[] from legacy domainName/authServerUrl (data migration)",
        "description": "One-off, manually-triggered migration utility for partners created before the domains[] array existed. Looks up the partner by accountId and, if it still has a legacy domainName+authServerUrl pair not yet reflected in domains[], appends one {domainName, authServerUrl} entry built from that pair. Idempotent: a partner with no legacy pair, or whose domains[] already contains it, is returned unchanged. No other field is touched.",
        "operationId": "migrateLegacyDomainToDomains",
        "parameters": [
          {
            "name": "accountId",
            "in": "query",
            "description": "The partner's Boomi Platform account ID.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "404": {
            "description": "No partner exists with this accountId.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "field": "tenantId",
                      "code": "PARTNER_NOT_FOUND",
                      "message": "Partner not found: acme-ABC123"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "accountId missing/blank. Bare {\"error\": \"...\"} shape (not the ErrorResponse envelope used elsewhere).",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {

                    }
                  }
                },
                "example": {
                  "error": "Required parameter 'accountId' is missing"
                }
              }
            }
          },
          "200": {
            "description": "Partner returned (migrated if needed, unchanged otherwise).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Partner"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid Boomi JWT bearer token. Empty body.",
            "content": {
              "application/json": {

              }
            }
          }
        },
        "security": [
          {
            "BoomiJwtBearer": []
          }
        ]
      }
    },
    "/v1/partners": {
      "get": {
        "tags": [
          "Partners"
        ],
        "summary": "Search/list partners",
        "description": "Returns a paged, optionally filtered/sorted list of partners.",
        "operationId": "getPartners",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "description": "Case-insensitive partial match on partnerName.",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "Acme"
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by active status (repeatable).",
            "required": false,
            "schema": {
              "enum": [
                "ACTIVE",
                "INACTIVE"
              ]
            },
            "example": "ACTIVE"
          },
          {
            "name": "dateAdded",
            "in": "query",
            "description": "Relative date-range filter on createdAt.",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Relative date-range preset: the last 30, 90, or 365 days.",
              "enum": [
                "LAST_30_DAYS",
                "LAST_90_DAYS",
                "LAST_365_DAYS"
              ]
            },
            "example": "LAST_30_DAYS"
          },
          {
            "name": "dateModified",
            "in": "query",
            "description": "Relative date-range filter on updatedAt.",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Relative date-range preset: the last 30, 90, or 365 days.",
              "enum": [
                "LAST_30_DAYS",
                "LAST_90_DAYS",
                "LAST_365_DAYS"
              ]
            },
            "example": "LAST_90_DAYS"
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Sort column, optionally suffixed with \",desc\" for descending order (default ascending, e.g. \"createdAt,desc\"); unknown columns return 400 INVALID_PARAM.",
            "required": false,
            "schema": {
              "enum": [
                "partnerName",
                "status",
                "createdAt",
                "updatedAt"
              ]
            },
            "example": "createdAt,desc"
          },
          {
            "name": "page",
            "in": "query",
            "description": "Zero-based page number.",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            },
            "example": 0
          },
          {
            "name": "size",
            "in": "query",
            "description": "Page size.",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 10
            },
            "example": 10
          }
        ],
        "responses": {
          "400": {
            "description": "Unknown/invalid sort column.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "field": null,
                      "code": "INVALID_PARAM",
                      "message": "Invalid sort column: bogus"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid Boomi JWT bearer token. Empty body.",
            "content": {
              "application/json": {

              }
            }
          },
          "200": {
            "description": "Page of matching partners.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "BoomiJwtBearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "Partners"
        ],
        "summary": "Onboard a new OEM partner",
        "description": "Creates a new partner. accountId is validated against the Boomi Platform (ACCOUNT_NOT_FOUND if it doesn't exist); partnerName/accountId must each be unique across active partners. domainName/authServerUrl (and domains[] entries) are not required to be unique — the same domain or issuer may be shared across multiple partners.\u003Cbr\u003E\u003Cbr\u003E\u003Cb\u003EKnown behavior:\u003C/b\u003E validation failures, ACCOUNT_NOT_FOUND, and duplicate-field conflicts are all collected together and currently returned as HTTP \u003Cb\u003E500\u003C/b\u003E (not 422/409), with one entry per problem in \u003Ccode\u003Eerrors[]\u003C/code\u003E — this documents the service's real, current behavior.",
        "operationId": "createPartner",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Partner created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Partner"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid Boomi JWT bearer token. Empty body.",
            "content": {
              "application/json": {

              }
            }
          },
          "500": {
            "description": "One or more validation/business-rule failures. Field validation, an unknown accountId, and duplicate-field conflicts can all appear here, individually or combined in the same errors[] array.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "Missing required fields": {
                    "value": {
                      "errors": [
                        {
                          "field": "partnerName",
                          "code": "REQUIRED",
                          "message": "must not be blank"
                        },
                        {
                          "field": "domainName",
                          "code": "REQUIRED",
                          "message": "must not be blank"
                        }
                      ]
                    }
                  },
                  "Invalid domainName format": {
                    "value": {
                      "errors": [
                        {
                          "field": "domainName",
                          "code": "INVALID_DOMAIN",
                          "message": "domainName must be a valid hostname ending with .com (no scheme, letters/digits/hyphens/dots)"
                        }
                      ]
                    }
                  },
                  "accountId not found on the platform": {
                    "value": {
                      "errors": [
                        {
                          "field": "accountId",
                          "code": "ACCOUNT_NOT_FOUND",
                          "message": "Account with accountId 'acme-ABC123' does not exist"
                        }
                      ]
                    }
                  },
                  "Duplicate partnerName + accountId": {
                    "value": {
                      "errors": [
                        {
                          "field": "partnerName",
                          "code": "DUPLICATE_NAME",
                          "message": "Partner with name 'Acme Corp' already exists"
                        },
                        {
                          "field": "accountId",
                          "code": "DUPLICATE_ACCOUNT_ID",
                          "message": "Partner with accountId 'acme-ABC123' already exists"
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "BoomiJwtBearer": []
          }
        ]
      }
    },
    "/logout": {
      "post": {
        "tags": [
          "Embed session"
        ],
        "summary": "Log out of the embed session",
        "description": "Invalidates the session and clears the session cookie. Public — no auth required. Only 204 is ever returned: internal DynamoDB failures during session deletion are caught and logged, never surfaced to the caller, so there is no observable error path for this endpoint.",
        "operationId": "logout",
        "responses": {
          "204": {
            "description": "Session invalidated (or was already gone); cookie cleared."
          }
        },
        "security": []
      }
    },
    "/embed-auth/route": {
      "post": {
        "tags": [
          "Embed session"
        ],
        "summary": "Record the SPA's current route",
        "description": "Records the active path on the caller's session so a subsequent GET /embed request carrying the same session cookie can preserve the path in the new session. Best-effort: the consumer UI fires this on every route change and ignores failures.",
        "operationId": "recordRoute",
        "requestBody": {
          "description": "The SPA's current in-app route.",
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "path": {
                    "description": "The active in-app path of the consumer UI, sanitized and validated server-side (see the 400 response). It is then replayed by GET /embed to restore state in the caller's next session.",
                    "example": "/settings/profile"
                  }
                }
              },
              "example": {
                "path": "/settings/profile"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "No active embed session (missing/expired session cookie). Empty body.",
            "content": {
              "application/json": {

              }
            }
          },
          "204": {
            "description": "Route recorded. Empty body."
          },
          "400": {
            "description": "path is missing or failed sanitization/validation. Empty body.",
            "content": {
              "application/json": {

              }
            }
          }
        },
        "security": []
      }
    },
    "/v1/partners/status": {
      "patch": {
        "tags": [
          "Partners"
        ],
        "summary": "Activate/deactivate a partner",
        "description": "Toggles a partner's active flag by uid. Despite the Java boolean type, the wire format for `active` is a JSON integer 0/1, not true/false — see the 422 response below.",
        "operationId": "updateStatus",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StatusRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Status updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Partner"
                }
              }
            }
          },
          "404": {
            "description": "No partner exists with this uid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "field": "tenantId",
                      "code": "PARTNER_NOT_FOUND",
                      "message": "Partner not found: 8f14e45f-ceea-467e-b7a9-53f68b6bab63"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid Boomi JWT bearer token. Empty body.",
            "content": {
              "application/json": {

              }
            }
          },
          "422": {
            "description": "uid or active missing/invalid (e.g. active sent as a real boolean instead of 0/1).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "field": "active",
                      "code": "REQUIRED",
                      "message": "active must not be null"
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "BoomiJwtBearer": []
          }
        ]
      }
    },
    "/v1/partners/default-space": {
      "patch": {
        "tags": [
          "Partners"
        ],
        "summary": "Clear a stale default Space GUID",
        "description": "Called by catalog-service when a Space is deleted, so any child account's defaultSpaceGuid pointing at that space is removed.",
        "operationId": "clearDefaultSpace",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClearDefaultSpaceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No childDetails entry pointed at this spaceGuid; nothing to clear.",
            "content": {
              "application/json": {

              }
            }
          },
          "422": {
            "description": "accountId or spaceGuid missing/blank.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "field": "spaceGuid",
                      "code": "REQUIRED",
                      "message": "spaceGuid must not be blank"
                    }
                  ]
                }
              }
            }
          },
          "200": {
            "description": "A matching childDetails entry was found and cleared; updated partner returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Partner"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid Boomi JWT bearer token. Empty body.",
            "content": {
              "application/json": {

              }
            }
          }
        },
        "security": [
          {
            "BoomiJwtBearer": []
          }
        ]
      }
    },
    "/v1/partners/lookup": {
      "get": {
        "tags": [
          "Partners"
        ],
        "summary": "Look up the caller's own partner record",
        "description": "Resolves the partner record for the caller's own account (accountId taken from the caller's JWT). Used by the publisher UI's Embeddable settings screen to show whether the logged-in account is already onboarded, and its full config if so.",
        "operationId": "getMyPartner",
        "responses": {
          "401": {
            "description": "Missing/invalid Boomi JWT bearer token. Empty body.",
            "content": {
              "application/json": {

              }
            }
          },
          "200": {
            "description": "Always 200; partner is null when the caller's account is not yet onboarded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerLookupResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "BoomiJwtBearer": []
          }
        ]
      }
    },
    "/v1/partners/jwt-platform-token": {
      "get": {
        "tags": [
          "Partners"
        ],
        "summary": "Resolve the embed redirect URL for a child user",
        "description": "Returns the Catalog consumer URL the caller should redirect to for this accountId/childEmailId. Response is a plain string, not JSON.",
        "operationId": "getJwtPlatformToken",
        "parameters": [
          {
            "name": "accountId",
            "in": "query",
            "description": "The partner's Boomi Platform account ID.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "childEmailId",
            "in": "query",
            "description": "The child user's email address.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Redirect target URL as plain text.",
            "content": {
              "text/plain": {
                "schema": {

                },
                "example": "https://scratch.space-service.cj-sandbox.boomi.com?guid"
              }
            }
          },
          "400": {
            "description": "Parameter validation failure. Two distinct causes share this bare {\"error\": \"...\"} shape (not the ErrorResponse envelope used elsewhere).",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {

                    }
                  }
                },
                "examples": {
                  "Invalid email format": {
                    "value": {
                      "error": "childEmailId: must be a well-formed email address"
                    }
                  },
                  "Missing required parameter": {
                    "value": {
                      "error": "Required parameter 'accountId' is missing"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid Boomi JWT bearer token. Empty body.",
            "content": {
              "application/json": {

              }
            }
          }
        },
        "security": [
          {
            "BoomiJwtBearer": []
          }
        ]
      }
    },
    "/health": {
      "get": {
        "tags": [
          "Health"
        ],
        "summary": "Liveness check",
        "description": "Returns 200 with the literal body \"ok\" when the service is up. No auth required. This route itself performs no downstream dependency checks and always returns 200 while the process is running.\n\nInfrastructure-level health is reported separately by the Spring Boot Actuator health endpoints (`/actuator/health`, `/actuator/health/readiness`, `/actuator/health/liveness`), which are not part of this API reference. The 503 response below documents that down signal, not a code path of this route.",
        "operationId": "health",
        "responses": {
          "503": {
            "description": "Service is down, as reported by the Spring Boot Actuator health endpoints above (not returned by this route directly).",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "status": {
                      "example": "DOWN"
                    }
                  }
                },
                "example": {
                  "status": "DOWN"
                }
              }
            }
          },
          "200": {
            "description": "Service is up.",
            "content": {
              "text/plain": {
                "schema": {

                },
                "example": "ok"
              }
            }
          }
        },
        "security": []
      }
    },
    "/embed": {
      "get": {
        "tags": [
          "Embed launch"
        ],
        "summary": "Launch the embedded Spaces iframe",
        "description": "Verifies the token against the resolved tenant's JWKS, guards against replay attacks using the `jti` claim, creates a session, sets the session cookie, and issues an HTTP 302 redirect to `/app/**`.\n\n**Error Handling:** All error responses return `text/html`. The HTTP status codes documented below represent the actual status returned (i.e., errors are not served as `200 OK` pages).",
        "operationId": "embed",
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "description": "Auth0-signed launch JWT (id_token).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "503": {
            "description": "Session could not be created (DynamoDB failure).",
            "content": {
              "text/html": {
                "schema": {

                },
                "example": "Could not start session. Please try again."
              }
            }
          },
          "400": {
            "description": "Missing/blank token.",
            "content": {
              "text/html": {
                "schema": {

                },
                "example": "Missing token. Use /embed?token=YOUR_SIGNED_JWT"
              }
            }
          },
          "403": {
            "description": "Unknown or disabled tenant for this token's issuer.",
            "content": {
              "text/html": {
                "schema": {

                },
                "example": "Unknown or disabled tenant for this token."
              }
            }
          },
          "302": {
            "description": "Session created; redirecting into the embedded app.",
            "headers": {
              "Set-Cookie": {
                "description": "Session cookie (httpOnly, Secure, SameSite=None, Partitioned).",
                "style": "simple",
                "schema": {
                  "example": "embed_session=3fa85f64-5717-4562-b3fc-2c963f66afa6; Path=/; Max-Age=28800; HttpOnly; Secure; SameSite=None; Partitioned"
                }
              },
              "Location": {
                "description": "Target app URL, e.g. /app/?guid=\u003CspaceGuid\u003E",
                "style": "simple",
                "schema": {
                  "example": "https://embed.boomi.com/app/?guid=8f14e45f-ceea-467e-abd2-4e8f8b2f1a1c"
                }
              }
            },
            "content": {
              "text/html": {
                "schema": {

                },
                "example": "No response body. See the Location and Set-Cookie response headers above."
              }
            }
          },
          "401": {
            "description": "Token failed verification: an invalid/expired signature, a missing email/sub claim, or a replayed token (jti already used).",
            "content": {
              "text/html": {
                "schema": {

                },
                "examples": {
                  "Invalid/expired signature": {
                    "value": "Invalid or expired token."
                  },
                  "Missing email/sub claim": {
                    "value": "Token has no email/sub claim."
                  },
                  "Replayed token": {
                    "value": "This launch link has already been used. Please relaunch."
                  }
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/embed-auth/me": {
      "get": {
        "tags": [
          "Embed session"
        ],
        "summary": "Get the caller's embed identity",
        "description": "Returns the non-secret identity the SPA needs to skip login and set the active space. No token is ever returned. Requires an active session (session cookie set by GET /embed).",
        "operationId": "getEmbedIdentity",
        "responses": {
          "401": {
            "description": "No active embed session (missing/expired session cookie). Empty body.",
            "content": {
              "application/json": {

              }
            }
          },
          "200": {
            "description": "Active session found.",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "spaceAccountId": {
                      "description": "The child account ID the SPA uses to build API URLs for the child's own resources; falls back to the parent accountId in single-tenant/demo mode (no childDetails).",
                      "example": "acme-child-001"
                    },
                    "spaceGuid": {
                      "description": "The Space GUID for the caller's active session. Empty string when none was resolved.",
                      "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                    },
                    "allowedOrigin": {
                      "description": "Per-session OEM parent origin, resolved from this partner's registered allowed origins. Used by the embedded UI as the postMessage target / inbound origin check. Empty string when none is configured.",
                      "example": "https://acme.com"
                    }
                  }
                },
                "example": {
                  "spaceAccountId": "acme-child-001",
                  "spaceGuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "allowedOrigin": "https://acme.com"
                }
              }
            }
          }
        },
        "security": []
      }
    }
  },
  "components": {
    "schemas": {
      "ChildDetailsRequest": {
        "type": "object",
        "description": "A child (sub-)account grant to create/update on a Partner.",
        "example": {
          "childAccountId": "acme-child-001",
          "childEmail": "user@acme.com",
          "childApiToken": "EXAMPLE_CHILD_API_TOKEN_7g8h9i0j",
          "defaultSpaceGuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
        },
        "properties": {
          "childAccountId": {
            "type": "string",
            "description": "The child (sub-)account's Boomi Platform account ID. Must already be a shared account of the parent accountId — see CHILD_ACCOUNT_ID_NOT_FOUND.",
            "example": "acme-child-001"
          },
          "childEmail": {
            "type": "string",
            "description": "Email identifying the child account holder. Once a childAccountId is registered with an email, it cannot be changed to a different email — see CHILD_EMAIL_MISMATCH.",
            "example": "user@acme.com"
          },
          "childApiToken": {
            "type": "string",
            "description": "SENSITIVE: Platform API token for the child account, used for child-first credential resolution in the embed/proxy flow.",
            "example": "EXAMPLE_CHILD_API_TOKEN_7g8h9i0j"
          },
          "defaultSpaceGuid": {
            "type": "string",
            "description": "The Space GUID this child account should land in by default.",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          }
        }
      },
      "DomainAuthEntryRequest": {
        "type": "object",
        "description": "A domain paired with the issuer that authenticates it, to register on a Partner.",
        "example": {
          "domainName": "acme.com",
          "authServerUrl": "https://acme.us.auth0.com/"
        },
        "properties": {
          "domainName": {
            "type": "string",
            "description": "Partner's domain, used to route embed requests. No scheme; must end in .com.",
            "example": "acme.com",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9\\-\\.]*\\.com$"
          },
          "authServerUrl": {
            "type": "string",
            "description": "The Auth0 (or equivalent OIDC) issuer URL used to verify this partner's embed launch tokens. May be shared across multiple partners.",
            "example": "https://acme.us.auth0.com/",
            "pattern": "^https://.*"
          }
        },
        "required": [
          "authServerUrl",
          "domainName"
        ]
      },
      "PartnerRequest": {
        "type": "object",
        "description": "Request payload to onboard a new OEM partner. domainName, authServerUrl, and apiToken are deprecated (superseded by domains and childDetails[].childApiToken, respectively) and are omitted from this example accordingly, but remain valid, settable fields for existing single-domain partners and fallback-token use. The example below shows their non-deprecated replacements, domains and childDetails[].childApiToken, instead.",
        "example": {
          "partnerName": "Acme Corp",
          "accountId": "acme-ABC123",
          "iframeUrl": "https://acme.com",
          "audience": "vQpfuHf8flLMggaCZ7uXzpZwdnDVi4Uh",
          "childDetails": [
            {
              "childAccountId": "acme-child-001",
              "childEmail": "user@acme.com",
              "childApiToken": "EXAMPLE_CHILD_API_TOKEN_7g8h9i0j",
              "defaultSpaceGuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            }
          ],
          "domains": [
            {
              "domainName": "acme.com",
              "authServerUrl": "https://acme.us.auth0.com/"
            }
          ]
        },
        "properties": {
          "partnerName": {
            "type": "string",
            "description": "Display name of the OEM partner.",
            "example": "Acme Corp"
          },
          "accountId": {
            "type": "string",
            "description": "The partner's Boomi Platform account ID. Must exist on the Boomi platform — see the ACCOUNT_NOT_FOUND error case.",
            "example": "acme-ABC123"
          },
          "domainName": {
            "type": "string",
            "deprecated": true,
            "description": "Partner's domain, used to route embed requests. No scheme; must end in .com.",
            "example": "acme.com",
            "pattern": "^$|^[a-zA-Z0-9][a-zA-Z0-9\\-\\.]*\\.com$"
          },
          "iframeUrl": {
            "type": "string",
            "description": "The OEM parent origin allowed to frame the embed (used for the per-tenant Content-Security-Policy frame-ancestors directive).",
            "example": "https://acme.com",
            "pattern": "^https?://[^\\s]+"
          },
          "authServerUrl": {
            "type": "string",
            "deprecated": true,
            "description": "The Auth0 (or equivalent OIDC) issuer URL used to verify this partner's embed launch tokens. May be shared across multiple partners.",
            "example": "https://acme.us.auth0.com/",
            "pattern": "^$|^https://.*"
          },
          "apiToken": {
            "type": "string",
            "deprecated": true,
            "description": "Boomi Platform API token used server-side to mint platform JWTs for this partner. Optional when every childDetails entry supplies its own childApiToken; falls back to this value where a child token is absent. SENSITIVE: currently returned as-is (unmasked) in every GET/POST/PUT/PATCH /v1/partners response — treat responses containing it accordingly. Deprecated: superseded by childDetails[].childApiToken.",
            "example": "EXAMPLE_API_TOKEN_1a2b3c4d5e6f",
            "pattern": "^$|^[A-Za-z0-9\\-_.]{8,512}$"
          },
          "audience": {
            "type": "string",
            "description": "Optional OIDC client ID (token `aud`). When set, it is validated against the launch token's aud claim. Note: incoming requests are currently routed by issuer (authServerUrl), regardless of whether this field is provided.",
            "example": "vQpfuHf8flLMggaCZ7uXzpZwdnDVi4Uh",
            "pattern": "^$|^[A-Za-z0-9_-]{8,128}$"
          },
          "childDetails": {
            "type": "array",
            "description": "Child (sub-)account grants for this partner. Each childAccountId must already be a shared account of accountId — see CHILD_ACCOUNT_ID_NOT_FOUND.",
            "items": {
              "$ref": "#/components/schemas/ChildDetailsRequest"
            }
          },
          "domains": {
            "type": "array",
            "description": "Domain + issuer pairs to register for this partner; supersedes the deprecated domainName/authServerUrl for multi-domain partners.",
            "items": {
              "$ref": "#/components/schemas/DomainAuthEntryRequest"
            },
            "maxItems": 20,
            "minItems": 0
          }
        },
        "required": [
          "accountId",
          "authServerUrl",
          "domainName",
          "iframeUrl",
          "partnerName"
        ]
      },
      "ErrorResponse": {
        "type": "object",
        "description": "Shared error envelope returned by most /v1/partners error responses (400/404/409/422/500). Almost always a single entry, except MethodArgumentNotValidException (422) and MultiFieldValidationException (500), which can report several.",
        "example": {
          "errors": [
            {
              "field": null,
              "code": "PARTNER_NOT_FOUND",
              "message": "Partner not found: 8f14e45f-ceea-467e-b7a9-53f68b6bab63"
            }
          ]
        },
        "properties": {
          "errors": {
            "type": "array",
            "description": "One entry per validation/business-rule error.",
            "items": {
              "$ref": "#/components/schemas/FieldError"
            }
          }
        }
      },
      "FieldError": {
        "type": "object",
        "description": "A single validation/business-rule error entry.",
        "example": {
          "field": null,
          "code": "PARTNER_NOT_FOUND",
          "message": "Partner not found: 8f14e45f-ceea-467e-b7a9-53f68b6bab63"
        },
        "properties": {
          "field": {
            "type": "string",
            "description": "Name of the offending request field, or null when the error isn't field-scoped (e.g. INVALID_PARAM)."
          },
          "code": {
            "type": "string",
            "description": "Machine-readable error code — one of the ErrorCode enum values.",
            "example": "PARTNER_NOT_FOUND"
          },
          "message": {
            "type": "string",
            "description": "Human-readable message.",
            "example": "Partner not found: 8f14e45f-ceea-467e-b7a9-53f68b6bab63"
          }
        }
      },
      "ChildDetails": {
        "type": "object",
        "description": "A child (sub-)account grant on a Partner.",
        "example": {
          "childAccountId": "acme-child-001",
          "childEmail": "user@acme.com",
          "childApiToken": "EXAMPLE_CHILD_API_TOKEN_7g8h9i0j",
          "defaultSpaceGuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
        },
        "properties": {
          "childAccountId": {
            "type": "string",
            "description": "The child (sub-)account's Boomi Platform account ID.",
            "example": "acme-child-001"
          },
          "childEmail": {
            "type": "string",
            "description": "Email identifying the child account holder.",
            "example": "user@acme.com"
          },
          "childApiToken": {
            "type": "string",
            "description": "SENSITIVE: Platform API token for the child account, returned as-is (unmasked) wherever this record is returned.",
            "example": "EXAMPLE_CHILD_API_TOKEN_7g8h9i0j"
          },
          "defaultSpaceGuid": {
            "type": "string",
            "description": "The Space GUID this child account lands in by default.",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          }
        }
      },
      "DomainAuthEntry": {
        "type": "object",
        "description": "A domain paired with the issuer that authenticates it, on a Partner.",
        "example": {
          "domainName": "acme.com",
          "authServerUrl": "https://acme.us.auth0.com/"
        },
        "properties": {
          "domainName": {
            "type": "string",
            "description": "Partner's domain, used to route embed requests.",
            "example": "acme.com"
          },
          "authServerUrl": {
            "type": "string",
            "description": "The Auth0 (or equivalent OIDC) issuer URL used to verify this partner's embed launch tokens.",
            "example": "https://acme.us.auth0.com/"
          }
        }
      },
      "Partner": {
        "type": "object",
        "description": "An onboarded OEM partner. Returned as-is by every GET/POST/PUT/PATCH /v1/partners response. domainName, authServerUrl, and apiToken are deprecated (superseded by domains and childDetails[].childApiToken, respectively) and are omitted from this example accordingly, but remain valid, settable fields for existing single-domain partners and fallback-token use. The example below shows their non-deprecated replacements, domains and childDetails[].childApiToken, instead.",
        "example": {
          "uid": "8f14e45f-ceea-467e-b7a9-53f68b6bab63",
          "partnerName": "Acme Corp",
          "accountId": "acme-ABC123",
          "iframeUrl": "https://acme.com",
          "audience": "vQpfuHf8flLMggaCZ7uXzpZwdnDVi4Uh",
          "sessionTimeout": 1800,
          "active": true,
          "createdAt": "2026-01-15T10:30:00Z",
          "updatedAt": "2026-02-01T09:00:00Z",
          "createdBy": "admin@boomi.com",
          "updatedBy": "admin@boomi.com",
          "childDetails": [
            {
              "childAccountId": "acme-child-001",
              "childEmail": "user@acme.com",
              "childApiToken": "EXAMPLE_CHILD_API_TOKEN_7g8h9i0j",
              "defaultSpaceGuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            }
          ],
          "domains": [
            {
              "domainName": "acme.com",
              "authServerUrl": "https://acme.us.auth0.com/"
            }
          ]
        },
        "properties": {
          "uid": {
            "type": "string",
            "description": "Unique partner identifier, generated server-side.",
            "example": "8f14e45f-ceea-467e-b7a9-53f68b6bab63"
          },
          "partnerName": {
            "type": "string",
            "description": "Display name of the OEM partner.",
            "example": "Acme Corp"
          },
          "accountId": {
            "type": "string",
            "description": "The partner's Boomi Platform account ID.",
            "example": "acme-ABC123"
          },
          "domainName": {
            "type": "string",
            "deprecated": true,
            "description": "Partner's domain, used to route embed requests.",
            "example": "acme.com"
          },
          "iframeUrl": {
            "type": "string",
            "description": "The OEM parent origin allowed to frame the embed.",
            "example": "https://acme.com"
          },
          "authServerUrl": {
            "type": "string",
            "deprecated": true,
            "description": "The Auth0 (or equivalent OIDC) issuer URL used to verify this partner's embed launch tokens.",
            "example": "https://acme.us.auth0.com/"
          },
          "apiToken": {
            "type": "string",
            "deprecated": true,
            "description": "Boomi Platform API token for this partner. SENSITIVE: currently returned as-is (unmasked) by GET/POST/PUT/PATCH /v1/partners — this documents real, current behavior rather than concealing it. Deprecated: superseded by per-child childDetails[].childApiToken; kept as the fallback token for children that don't supply their own.",
            "example": "EXAMPLE_API_TOKEN_1a2b3c4d5e6f"
          },
          "audience": {
            "type": "string",
            "description": "Optional OIDC client id (token `aud`) used as an additional lookup key for the embed flow.",
            "example": "vQpfuHf8flLMggaCZ7uXzpZwdnDVi4Uh"
          },
          "sessionTimeout": {
            "type": "integer",
            "format": "int32",
            "description": "Session timeout in seconds for this partner's embed sessions.",
            "example": 1800
          },
          "active": {
            "type": "boolean",
            "description": "Whether this partner is active.",
            "example": true
          },
          "createdAt": {
            "type": "string",
            "description": "ISO-8601 timestamp this partner record was created.",
            "example": "2026-01-15T10:30:00Z"
          },
          "updatedAt": {
            "type": "string",
            "description": "ISO-8601 timestamp this partner record was last updated.",
            "example": "2026-02-01T09:00:00Z"
          },
          "createdBy": {
            "type": "string",
            "description": "Identity that created this partner record.",
            "example": "admin@boomi.com"
          },
          "updatedBy": {
            "type": "string",
            "description": "Identity that last updated this partner record.",
            "example": "admin@boomi.com"
          },
          "childDetails": {
            "type": "array",
            "description": "Child (sub-)account grants for this partner.",
            "items": {
              "$ref": "#/components/schemas/ChildDetails"
            }
          },
          "domains": {
            "type": "array",
            "description": "Domain + issuer pairs registered for this partner; supersedes the deprecated domainName/authServerUrl for multi-domain partners.",
            "items": {
              "$ref": "#/components/schemas/DomainAuthEntry"
            }
          }
        }
      },
      "PartnerPatchRequest": {
        "type": "object",
        "description": "Partial-update payload for an existing partner; every field is optional and omitted/null fields are left unchanged. domainName, authServerUrl, and apiToken are deprecated (superseded by domains and childDetails[].childApiToken, respectively) and are omitted from this example accordingly, but remain valid, settable fields for existing single-domain partners and fallback-token use.",
        "example": {
          "iframeUrl": "https://acme.com",
          "domains": [
            {
              "domainName": "acme.com",
              "authServerUrl": "https://acme.us.auth0.com/"
            }
          ]
        },
        "properties": {
          "partnerName": {
            "type": "string",
            "description": "Display name of the OEM partner. Omit/null to leave unchanged.",
            "example": "Acme Corp"
          },
          "accountId": {
            "type": "string",
            "description": "The partner's Boomi Platform account ID. Omit/null to leave unchanged.",
            "example": "acme-ABC123"
          },
          "domainName": {
            "type": "string",
            "deprecated": true,
            "description": "Partner's domain. Omit/null to leave unchanged; if provided, must be a valid hostname ending in .com.",
            "example": "acme.com",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9\\-\\.]*\\.com$"
          },
          "iframeUrl": {
            "type": "string",
            "description": "The OEM parent origin allowed to frame the embed. Omit/null to leave unchanged.",
            "example": "https://acme.com",
            "pattern": "^https?://[^\\s]+"
          },
          "authServerUrl": {
            "type": "string",
            "deprecated": true,
            "description": "The Auth0 (or equivalent OIDC) issuer URL. Omit/null to leave unchanged.",
            "example": "https://acme.us.auth0.com/",
            "pattern": "^https://.*"
          },
          "apiToken": {
            "type": "string",
            "deprecated": true,
            "description": "The Boomi Platform API token used server-side to mint platform JWTs for this partner. SECURITY NOTE: This token is returned unmasked in all GET, POST, PUT, and PATCH responses for /v1/partners. Handle and store response payloads containing this field with appropriate security controls. Omit/null to leave unchanged. Deprecated: superseded by childDetails[].childApiToken.",
            "example": "EXAMPLE_API_TOKEN_1a2b3c4d5e6f",
            "pattern": "^[A-Za-z0-9\\-_.]{8,512}$"
          },
          "audience": {
            "type": "string",
            "description": "Optional OIDC client id (token `aud`). Omit/null to leave unchanged.",
            "example": "vQpfuHf8flLMggaCZ7uXzpZwdnDVi4Uh",
            "pattern": "^$|^[A-Za-z0-9_-]{8,128}$"
          },
          "childDetails": {
            "type": "array",
            "description": "Child (sub-)account grants for this partner. Omit/null to leave unchanged.",
            "items": {
              "$ref": "#/components/schemas/ChildDetailsRequest"
            }
          },
          "domains": {
            "type": "array",
            "description": "Domain + issuer pairs for this partner; supersedes the deprecated domainName/authServerUrl for multi-domain partners. Omit/null to leave unchanged; when present, replaces the whole list.",
            "items": {
              "$ref": "#/components/schemas/DomainAuthEntryRequest"
            }
          }
        }
      },
      "StatusRequest": {
        "type": "object",
        "description": "Request to update a partner's active status.",
        "example": {
          "uid": "8f14e45f-ceea-467e-b7a9-53f68b6bab63",
          "active": 1
        },
        "properties": {
          "uid": {
            "type": "string",
            "description": "Partner uid to update.",
            "example": "8f14e45f-ceea-467e-b7a9-53f68b6bab63"
          },
          "active": {
            "type": "integer",
            "format": "int32",
            "description": "The desired active status. Note: despite the internal Java boolean type, the wire format requires a JSON integer (0 for inactive, 1 for active). Standard JSON boolean values (true/false) will be rejected with an HTTP 400 error by a custom deserializer.",
            "example": 1,
            "maximum": 1,
            "minimum": 0
          }
        },
        "required": [
          "active",
          "uid"
        ]
      },
      "ClearDefaultSpaceRequest": {
        "type": "object",
        "description": "Request to clear a deleted Space's GUID from any matching childDetails.defaultSpaceGuid entry under a given partner account.",
        "example": {
          "accountId": "acme-ABC123",
          "spaceGuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
        },
        "properties": {
          "accountId": {
            "type": "string",
            "description": "The parent (OEM) account whose childDetails entries should be checked.",
            "example": "acme-ABC123"
          },
          "spaceGuid": {
            "type": "string",
            "description": "The deleted Space's GUID; cleared from any childDetails.defaultSpaceGuid entry that currently points at it.",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          }
        },
        "required": [
          "accountId",
          "spaceGuid"
        ]
      },
      "PageResponse": {
        "type": "object",
        "description": "A single page of results.",
        "example": {
          "content": [],
          "page": 0,
          "size": 10,
          "totalElements": 42,
          "totalPages": 5
        },
        "properties": {
          "content": {
            "type": "array",
            "description": "The items on this page.",
            "items": {

            }
          },
          "page": {
            "type": "integer",
            "format": "int32",
            "description": "Zero-based page number requested.",
            "example": 0
          },
          "size": {
            "type": "integer",
            "format": "int32",
            "description": "Requested page size.",
            "example": 10
          },
          "totalElements": {
            "type": "integer",
            "format": "int64",
            "description": "Total number of items across all pages.",
            "example": 42
          },
          "totalPages": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of pages.",
            "example": 5
          }
        }
      },
      "PartnerLookupResponse": {
        "type": "object",
        "description": "Response wrapper for the caller's own partner lookup.",
        "example": {
          "partner": {
            "uid": "8f14e45f-ceea-467e-b7a9-53f68b6bab63",
            "partnerName": "Acme Corp",
            "accountId": "acme-ABC123",
            "active": true
          }
        },
        "properties": {
          "partner": {
            "$ref": "#/components/schemas/Partner",
            "description": "The caller's partner record, or null when the caller's account is not yet onboarded as a partner."
          }
        }
      }
    },
    "securitySchemes": {
      "BoomiJwtBearer": {
        "type": "http",
        "description": "Boomi-internal JWT bearer token. Required on every /v1/partners/** endpoint; a request without a valid token carrying the BOOMI_INTERNAL authority is rejected with 401 before it reaches the controller (empty body).",
        "in": "header",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  }
}