{
  "openapi": "3.0.3",
  "info": {
    "title": "GigaGlobe API",
    "version": "v1",
    "description": "Domains, SSL certificates, and managed hosting — programmable.\n\nGigaGlobe is an ICANN-accredited registrar with DirectAdmin hosting and DV/OV/EV/Wildcard SSL. Tenants integrate via this REST API; we own the infrastructure, you own your customers.\n\n**Authentication.** Bearer keys with the format `gg_<env>_pk_<32 base62>`. The first ~12 characters (prefix) are safe to log. The plaintext is shown exactly once at mint time.\n\n**Envelope.** Every response is JSON: `{ data, meta:{ request_id } }` for success, `{ data:[…], total, has_more, meta }` for lists, `{ error:{ type, code, message, param? }, meta }` for failures. Every response includes the `X-Request-Id` header.\n\n**Idempotency.** Mutating endpoints accept the `Idempotency-Key` header. Retries with the same key inside 24 hours return the original result.\n\n**Async work.** Endpoints that hit the registrar / CA / DirectAdmin return 202 with a pending resource. Subscribe to the matching webhook event (e.g. `domain.registered`, `ssl.issued`, `hosting.provisioned`) to know when it completes.\n\nFull contract: https://gigaglobe.com/developers",
    "contact": { "name": "GigaGlobe API support", "email": "support@gigaglobe.com", "url": "https://gigaglobe.com/developers" },
    "license": { "name": "Commercial", "url": "https://gigaglobe.com/about" }
  },
  "servers": [
    { "url": "https://api.gigaglobe.com/api/v1", "description": "Production" },
    { "url": "http://localhost:8730/api/v1",    "description": "Local development" }
  ],
  "security": [{ "BearerAuth": [] }],
  "tags": [
    { "name": "Identity",     "description": "Verify your key works." },
    { "name": "Domains",      "description": "Registration, transfer, renewal, nameservers." },
    { "name": "DNS",          "description": "Hosted DNS records for your domains." },
    { "name": "SSL",          "description": "DV / OV / EV / wildcard certificates." },
    { "name": "Hosting",      "description": "DirectAdmin shared-hosting accounts." },
    { "name": "Billing",      "description": "Read-only audit of orders and invoices." },
    { "name": "Webhooks",     "description": "Subscribe to events; we sign every payload." },
    { "name": "Usage",        "description": "Daily request counts, error rate, latency." }
  ],
  "paths": {
    "/me": {
      "get": {
        "tags": ["Identity"], "summary": "Sanity-check your Bearer key",
        "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" } }
      }
    },
    "/domains": {
      "get": {
        "tags": ["Domains"], "summary": "List your tenant's domains",
        "parameters": [{ "$ref": "#/components/parameters/Limit" }, { "$ref": "#/components/parameters/StartingAfter" }],
        "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DomainList" } } } } }
      },
      "post": {
        "tags": ["Domains"], "summary": "Register a new domain (async)",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DomainRegisterRequest" }, "example": { "name": "acmecorp.com", "customer_id": "cust_42abc", "years": 2, "nameservers": ["ns1.gigaglobe.com", "ns2.gigaglobe.com"] } } } },
        "responses": { "202": { "description": "Accepted — domain is pending. Watch the `domain.registered` webhook.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DomainResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "409": { "$ref": "#/components/responses/Conflict" } }
      }
    },
    "/domains/search": {
      "post": {
        "tags": ["Domains"], "summary": "Search availability + pricing across your price book",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["query"], "properties": { "query": { "type": "string", "example": "acmecorp" } } } } } },
        "responses": { "200": { "description": "OK" } }
      }
    },
    "/domains/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/DomainId" }],
      "get":   { "tags": ["Domains"], "summary": "Show a domain",  "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DomainResponse" } } } }, "404": { "$ref": "#/components/responses/NotFound" } } },
      "patch": { "tags": ["Domains"], "summary": "Update nameservers / auto_renew / customer_id", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DomainPatchRequest" } } } }, "responses": { "200": { "description": "OK" }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" } } }
    },
    "/domains/{id}/availability": {
      "parameters": [{ "$ref": "#/components/parameters/DomainId" }],
      "get": { "tags": ["Domains"], "summary": "Live availability check", "responses": { "200": { "description": "OK" } } }
    },
    "/domains/{id}/transfer": {
      "parameters": [{ "$ref": "#/components/parameters/DomainId" }],
      "post": { "tags": ["Domains"], "summary": "Inbound transfer (async)", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["customer_id", "auth_code"], "properties": { "customer_id": { "type": "string" }, "auth_code": { "type": "string", "description": "EPP / authcode from the losing registrar." } } } } } }, "responses": { "202": { "description": "Accepted" } } }
    },
    "/domains/{id}/renew": {
      "parameters": [{ "$ref": "#/components/parameters/DomainId" }],
      "post": { "tags": ["Domains"], "summary": "Renew (async)", "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "properties": { "years": { "type": "integer", "minimum": 1, "maximum": 10, "default": 1 } } } } } }, "responses": { "202": { "description": "Accepted" } } }
    },
    "/domains/{id}/dns": {
      "parameters": [{ "$ref": "#/components/parameters/DomainId" }],
      "get":  { "tags": ["DNS"], "summary": "List DNS records", "responses": { "200": { "description": "OK" } } },
      "post": { "tags": ["DNS"], "summary": "Create a DNS record", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DnsRecordRequest" } } } }, "responses": { "201": { "description": "Created" }, "400": { "$ref": "#/components/responses/BadRequest" } } }
    },
    "/domains/{id}/dns/{record}": {
      "parameters": [{ "$ref": "#/components/parameters/DomainId" }, { "name": "record", "in": "path", "required": true, "schema": { "type": "string", "example": "dns_1" } }],
      "delete": { "tags": ["DNS"], "summary": "Delete a DNS record", "responses": { "204": { "description": "No content" } } }
    },
    "/ssl": {
      "get":  { "tags": ["SSL"], "summary": "List certificates", "parameters": [{ "$ref": "#/components/parameters/Limit" }, { "$ref": "#/components/parameters/StartingAfter" }], "responses": { "200": { "description": "OK" } } },
      "post": { "tags": ["SSL"], "summary": "Issue a certificate (async)", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SslIssueRequest" } } } }, "responses": { "202": { "description": "Accepted" }, "400": { "$ref": "#/components/responses/BadRequest" } } }
    },
    "/ssl/{id}": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "example": "ssl_1" } }],
      "get": { "tags": ["SSL"], "summary": "Show a certificate", "responses": { "200": { "description": "OK" }, "404": { "$ref": "#/components/responses/NotFound" } } }
    },
    "/ssl/{id}/renew":   { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }], "post": { "tags": ["SSL"], "summary": "Renew", "responses": { "202": { "description": "Accepted" } } } },
    "/ssl/{id}/reissue": { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }], "post": { "tags": ["SSL"], "summary": "Reissue", "responses": { "202": { "description": "Accepted" } } } },
    "/hosting": {
      "get":  { "tags": ["Hosting"], "summary": "List hosting accounts", "responses": { "200": { "description": "OK" } } },
      "post": { "tags": ["Hosting"], "summary": "Provision (async)", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HostingProvisionRequest" } } } }, "responses": { "202": { "description": "Accepted" }, "400": { "$ref": "#/components/responses/BadRequest" } } }
    },
    "/hosting/{id}":            { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "example": "hst_1" } }], "get":  { "tags": ["Hosting"], "summary": "Show", "responses": { "200": { "description": "OK" } } } },
    "/hosting/{id}/suspend":    { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }], "post": { "tags": ["Hosting"], "summary": "Suspend",   "responses": { "202": { "description": "Accepted" } } } },
    "/hosting/{id}/unsuspend":  { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }], "post": { "tags": ["Hosting"], "summary": "Unsuspend", "responses": { "202": { "description": "Accepted" } } } },
    "/hosting/{id}/password":   { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }], "post": { "tags": ["Hosting"], "summary": "Rotate password — returns a one-time transient password", "responses": { "200": { "description": "OK" } } } },
    "/orders":                  { "get":  { "tags": ["Billing"], "summary": "List orders",  "parameters": [{ "$ref": "#/components/parameters/Limit" }, { "$ref": "#/components/parameters/StartingAfter" }], "responses": { "200": { "description": "OK" } } } },
    "/orders/{id}":             { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "example": "ord_1" } }], "get": { "tags": ["Billing"], "summary": "Show an order with line items", "responses": { "200": { "description": "OK" }, "404": { "$ref": "#/components/responses/NotFound" } } } },
    "/invoices":                { "get":  { "tags": ["Billing"], "summary": "List invoices", "responses": { "200": { "description": "OK" } } } },
    "/invoices/{id}":           { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "example": "inv_1" } }], "get":  { "tags": ["Billing"], "summary": "Show an invoice with line items", "responses": { "200": { "description": "OK" } } } },
    "/webhooks": {
      "get":  { "tags": ["Webhooks"], "summary": "List subscriptions", "responses": { "200": { "description": "OK" } } },
      "post": { "tags": ["Webhooks"], "summary": "Subscribe — returns signing secret once", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookCreateRequest" } } } }, "responses": { "201": { "description": "Created" } } }
    },
    "/webhooks/{id}":           { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "example": "whk_1" } }], "patch":  { "tags": ["Webhooks"], "summary": "Update url / events / is_active", "responses": { "200": { "description": "OK" } } }, "delete": { "tags": ["Webhooks"], "summary": "Delete",   "responses": { "204": { "description": "No content" } } } },
    "/webhooks/{id}/test":      { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }], "post": { "tags": ["Webhooks"], "summary": "Send webhook.ping", "responses": { "202": { "description": "Queued" } } } },
    "/usage":                   { "get":  { "tags": ["Usage"], "summary": "30-day request counts, error rate, latency", "responses": { "200": { "description": "OK" } } } }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "gg_<env>_pk_<32 base62>" }
    },
    "parameters": {
      "Limit":          { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 } },
      "StartingAfter":  { "name": "starting_after", "in": "query", "required": false, "schema": { "type": "string", "description": "Opaque cursor — current implementation accepts a row id." } },
      "DomainId":       { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "example": "dom_1", "description": "Either `dom_<n>` or the bare FQDN (e.g. `example.com`)." } }
    },
    "responses": {
      "Unauthorized": { "description": "Missing or invalid API key.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": { "type": "authentication_error", "code": "unauthenticated", "message": "No valid API key provided." }, "meta": { "request_id": "abc123" } } } } },
      "Forbidden":    { "description": "This key lacks the required scope.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "NotFound":     { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "BadRequest":   { "description": "Validation error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Conflict":     { "description": "Resource conflict.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    },
    "schemas": {
      "Meta":        { "type": "object", "properties": { "request_id": { "type": "string", "description": "32-hex correlator. Also returned in X-Request-Id." } } },
      "Error":       { "type": "object", "properties": { "error": { "type": "object", "required": ["type", "code", "message"], "properties": { "type": { "type": "string", "enum": ["authentication_error", "permission_error", "invalid_request_error", "rate_limit_error", "api_error"] }, "code": { "type": "string" }, "message": { "type": "string" }, "param": { "type": "string" } } }, "meta": { "$ref": "#/components/schemas/Meta" } } },
      "Domain":      { "type": "object", "properties": { "object": { "type": "string", "example": "domain" }, "id": { "type": "string", "example": "dom_42" }, "name": { "type": "string" }, "tld": { "type": "string" }, "status": { "type": "string", "enum": ["pending", "active", "transfer_pending", "renewal_pending", "expired", "deleted"] }, "auto_renew": { "type": "boolean" }, "nameservers": { "type": "array", "items": { "type": "string" } }, "epp_code": { "type": "string", "nullable": true }, "customer_id": { "type": "string" }, "registered_at": { "type": "string", "format": "date-time", "nullable": true }, "expires_at": { "type": "string", "format": "date-time", "nullable": true }, "created_at": { "type": "string", "format": "date-time" } } },
      "DomainList":  { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Domain" } }, "total": { "type": "integer" }, "has_more": { "type": "boolean" }, "meta": { "$ref": "#/components/schemas/Meta" } } },
      "DomainResponse": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Domain" }, "meta": { "$ref": "#/components/schemas/Meta" } } },
      "DomainRegisterRequest": { "type": "object", "required": ["name", "customer_id"], "properties": { "name": { "type": "string", "example": "acmecorp.com" }, "customer_id": { "type": "string", "example": "cust_42abc" }, "years": { "type": "integer", "minimum": 1, "maximum": 10, "default": 1 }, "nameservers": { "type": "array", "items": { "type": "string" } } } },
      "DomainPatchRequest":    { "type": "object", "properties": { "nameservers": { "type": "array", "items": { "type": "string" } }, "auto_renew": { "type": "boolean" }, "customer_id": { "type": "string" } } },
      "DnsRecordRequest": { "type": "object", "required": ["type", "value"], "properties": { "type": { "type": "string", "enum": ["A", "AAAA", "CNAME", "MX", "TXT", "NS", "SRV", "CAA"] }, "host": { "type": "string", "default": "@" }, "value": { "type": "string" }, "ttl": { "type": "integer", "minimum": 60, "maximum": 86400, "default": 3600 }, "priority": { "type": "integer", "description": "Required for MX records." } } },
      "SslIssueRequest": { "type": "object", "required": ["common_name", "customer_id"], "properties": { "common_name": { "type": "string", "example": "app.acmecorp.com" }, "cert_type": { "type": "string", "enum": ["dv", "ov", "ev", "wildcard"], "default": "dv" }, "customer_id": { "type": "string" }, "san_names": { "type": "array", "items": { "type": "string" } } } },
      "HostingProvisionRequest": { "type": "object", "required": ["domain", "package", "customer_id"], "properties": { "domain": { "type": "string", "example": "acmecorp.com" }, "package": { "type": "string", "example": "starter" }, "customer_id": { "type": "string" }, "username": { "type": "string", "description": "Optional. 2–16 lowercase alphanumeric, must start with a letter.", "pattern": "^[a-z][a-z0-9]{1,15}$" } } },
      "WebhookCreateRequest": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string", "format": "uri", "example": "https://your.app/gigaglobe/webhook" }, "events": { "type": "array", "items": { "type": "string" }, "description": "Exact event names (e.g. `ssl.issued`), globs (e.g. `domain.*`), or `*`. Defaults to `[\"*\"]`." } } },
      "MeResponse": { "type": "object", "properties": { "data": { "type": "object", "properties": { "tenant": { "type": "object" }, "api_key": { "type": "object" } } }, "meta": { "$ref": "#/components/schemas/Meta" } } }
    }
  }
}
