{
  "openapi": "3.1.0",
  "info": {
    "title": "Ulinkly Public API",
    "version": "1.0.0",
    "summary": "Create, resolve, and measure mobile deep links.",
    "description": "The versioned public Ulinkly API for mobile deep-link infrastructure. Public discovery operations require no credentials; link creation and SDK telemetry use a project-scoped X-App-Key. Create keys self-serve in the Ulinkly dashboard. A free plan is available without a credit card. Version lifecycle, deprecation, rate-limit, and typed-error conventions are documented under externalDocs.",
    "termsOfService": "https://ulink.ly/terms",
    "contact": {
      "name": "Ulinkly Support",
      "email": "support@ulink.ly",
      "url": "https://ulink.ly/contact"
    },
    "license": {
      "name": "Proprietary API; SDKs and tools have their own licenses",
      "url": "https://ulink.ly/terms"
    }
  },
  "externalDocs": {
    "description": "Ulinkly REST API documentation and integration guides",
    "url": "https://docs.ulink.ly/rest-api/overview"
  },
  "servers": [
    {
      "url": "https://api.ulink.ly/v1",
      "description": "Production API v1"
    },
    {
      "url": "https://api.ulink.ly",
      "description": "Deprecated unversioned compatibility base; use /v1. See https://docs.ulink.ly/rest-api/versioning.",
      "x-deprecated": true,
      "x-deprecation-date": "2026-08-25"
    }
  ],
  "tags": [
    {
      "name": "Discovery",
      "description": "Unauthenticated operations for health, plans, and link resolution."
    },
    {
      "name": "Links",
      "description": "Project-scoped operations for creating and reading deep links."
    },
    {
      "name": "Installations",
      "description": "SDK operations for installation and session analytics."
    },
    {
      "name": "Deferred deep links",
      "description": "Match installs to earlier link clicks."
    }
  ],
  "paths": {
    "/health": {
      "get": {
        "operationId": "getApiHealth",
        "summary": "Check API health",
        "description": "Returns the current public API status without authentication. Use this operation to verify connectivity before starting an integration.",
        "tags": ["Discovery"],
        "security": [],
        "responses": {
          "200": {
            "description": "The API is healthy.",
            "headers": {
              "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/subscriptions/plans": {
      "get": {
        "operationId": "listSubscriptionPlans",
        "summary": "List available plans",
        "description": "Returns current Ulinkly plans, limits, and features without authentication. Prices are returned for the requested billing period.",
        "tags": ["Discovery"],
        "security": [],
        "parameters": [
          {
            "name": "billingPeriod",
            "in": "query",
            "required": false,
            "description": "Billing period used for returned prices.",
            "schema": {
              "type": "string",
              "enum": ["monthly", "yearly"],
              "default": "monthly"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Available plans and their current limits.",
            "headers": {
              "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlansResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/sdk/resolve": {
      "get": {
        "operationId": "resolveDeepLink",
        "summary": "Resolve a deep link",
        "description": "Resolves a full Ulinkly web URL or app-scheme URL to its typed destination and parameters. This public operation also records a click for the owning project.",
        "tags": ["Discovery", "Links"],
        "security": [],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Full HTTPS deep-link URL or custom-scheme URL to resolve.",
            "schema": {
              "type": "string",
              "minLength": 3,
              "examples": ["https://example.shared.ly/welcome"]
            }
          },
          {
            "name": "X-Installation-Token",
            "in": "header",
            "required": false,
            "description": "Optional installation token returned by installation tracking.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Resolved link data and destination parameters.",
            "headers": {
              "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResolvedLink"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/sdk/links": {
      "post": {
        "operationId": "createDeepLink",
        "summary": "Create a deep link",
        "description": "Creates a unified or dynamic link for the project identified by X-App-Key. Supplying a stable externalId makes repeated requests idempotent and returns the existing link.",
        "tags": ["Links"],
        "security": [
          {
            "AppKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Link routing, fallback, attribution, and preview configuration.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLinkRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "A new link was created.",
            "headers": {
              "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Link"
                }
              }
            }
          },
          "200": {
            "description": "An existing idempotent link was returned.",
            "headers": {
              "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Link"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/sdk/links/{slug}": {
      "get": {
        "operationId": "getDeepLinkBySlug",
        "summary": "Get a project link by slug",
        "description": "Returns a link owned by the project associated with X-App-Key. Slugs are scoped to the authenticated project.",
        "tags": ["Links"],
        "security": [
          {
            "AppKey": []
          }
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Project-scoped link slug.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested project link.",
            "headers": {
              "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResolvedLink"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/sdk/bootstrap": {
      "post": {
        "operationId": "bootstrap",
        "summary": "Bootstrap an installation and session",
        "description": "Ensures the installation exists, starts or reuses an active session, and returns an installation token. This is the call the mobile SDKs make at startup. It creates or reuses a session on every plan and reports reinstall detection; send a stable `persistentDeviceId` to deduplicate reinstalls.",
        "tags": [
          "Installations"
        ],
        "security": [
          {
            "AppKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Installation identity, optional persistent device identity, device context, and session context.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BootstrapRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Installation ensured and session active.",
            "headers": {
              "X-Installation-Token": {
                "description": "Installation token also included in the response body.",
                "schema": {
                  "type": "string"
                }
              },
              "ULink-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BootstrapResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/SessionAdmissionForbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/sdk/deferred/match": {
      "post": {
        "operationId": "matchDeferredLink",
        "summary": "Match a deferred deep link after install",
        "description": "Matches a fresh install to an earlier link click so the app can open the intended content. Uses a click identifier when available (deterministic) or a fingerprint of the IP address, screen width, and timezone (probabilistic; a match is not guaranteed). Clicks are eligible for 24 hours. Available on paid plans; on the Free plan the response has `success: false` and an `error` message.",
        "tags": [
          "Deferred deep links"
        ],
        "security": [
          {
            "AppKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Click identifier and/or device fingerprint captured on first launch.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeferredMatchRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Match attempted. Check `success` for the outcome.",
            "headers": {
              "ULink-API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeferredMatchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/sdk/installations/track": {
      "post": {
        "operationId": "trackInstallation",
        "summary": "Track an app installation",
        "description": "Creates or refreshes a project installation record and returns an installation token for subsequent SDK calls. Call once per app installation or when the stored token expires.",
        "tags": ["Installations"],
        "security": [
          {
            "AppKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Per-install identifier plus optional persistent device identity and device context.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TrackInstallationRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Installation tracked and token issued.",
            "headers": {
              "X-Installation-Token": {
                "description": "Installation token also included in the response body.",
                "schema": {
                  "type": "string"
                }
              },
              "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrackInstallationResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/sdk/sessions/start": {
      "post": {
        "operationId": "startInstallationSession",
        "summary": "Start an app session",
        "description": "Starts an analytics session for a previously tracked installation. Send the project X-App-Key and the stable installationId.",
        "tags": ["Installations"],
        "security": [
          {
            "AppKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Installation identifier and optional current device state.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartSessionRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Session started.",
            "headers": {
              "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartSessionResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/SessionAdmissionForbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/sdk/sessions/{sessionId}/end": {
      "post": {
        "operationId": "endInstallationSession",
        "summary": "End an app session",
        "description": "Ends an active installation session and finalizes its duration for analytics.",
        "tags": ["Installations"],
        "security": [
          {
            "AppKey": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "Session identifier returned by startInstallationSession.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Session ended.",
            "headers": {
              "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "AppKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-App-Key",
        "description": "Project-scoped API key created under Dashboard → API Keys. Keep it out of public client code when possible."
      }
    },
    "headers": {
      "ApiVersion": {
        "description": "Resolved major API version.",
        "schema": { "type": "string", "const": "1" }
      },
      "RateLimitPolicy": {
        "description": "Quota policy as an IETF Structured Field. See https://docs.ulink.ly/rest-api/rate-limits.",
        "schema": { "type": "string", "examples": ["\"public-api\";q=6000;w=60"] }
      },
      "RateLimit": {
        "description": "Live remaining quota and effective window as an IETF Structured Field.",
        "schema": { "type": "string", "examples": ["\"public-api\";r=5999;t=60"] }
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying a rate-limited request.",
        "schema": { "type": "integer", "minimum": 1 }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request failed validation.",
        "headers": {
          "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "X-App-Key is missing or invalid.",
        "headers": {
          "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The operation is not permitted for the current plan or usage state.",
        "headers": {
          "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "SessionAdmissionForbidden": {
        "description": "Session admission is not permitted for the current plan or usage state. Current causes include no eligible plan, a new SDK identity reaching the Free plan's 10,000 MAU monthly capacity, a paid project reaching its MAU allowance while its overage policy is frozen, or another enforced plan resource limit such as custom domains or team members. Previously admitted Free identities remain allowed for the rest of the UTC calendar month.",
        "headers": {
          "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "The requested link, installation, session, project, or domain was not found.",
        "headers": {
          "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "The API is temporarily unavailable.",
        "headers": {
          "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "The client exhausted its current request quota.",
        "headers": {
          "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" },
          "Retry-After": { "$ref": "#/components/headers/RetryAfter" }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "InternalServerError": {
        "description": "The API could not complete the request.",
        "headers": {
          "ULink-API-Version": { "$ref": "#/components/headers/ApiVersion" },
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    },
    "schemas": {
      "HealthResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["status", "timestamp", "environment"],
        "properties": {
          "status": {
            "type": "string",
            "const": "ok"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "environment": {
            "type": "string",
            "examples": ["production"]
          }
        }
      },
      "PlansResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["plans"],
        "properties": {
          "plans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Plan"
            }
          }
        }
      },
      "Plan": {
        "type": "object",
        "required": ["name", "priceId", "price", "period", "billingPeriod", "features", "limits", "hasOverage"],
        "properties": {
          "name": { "type": "string" },
          "priceId": { "type": "string" },
          "stripePriceId": { "type": ["string", "null"] },
          "price": { "type": "string", "examples": ["$0"] },
          "period": { "type": "string", "examples": ["/month"] },
          "billingPeriod": { "type": "string", "enum": ["monthly", "yearly"] },
          "yearlyDiscount": { "type": ["string", "null"] },
          "features": { "type": "array", "items": { "type": "string" } },
          "limits": { "type": "object", "additionalProperties": true },
          "hasOverage": { "type": "boolean" },
          "overageRatePer1k": { "type": ["number", "null"] }
        }
      },
      "ResolvedLink": {
        "type": "object",
        "required": ["id", "slug", "type"],
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "slug": { "type": "string" },
          "type": { "type": "string", "enum": ["unified", "dynamic"] },
          "fallbackUrl": { "type": ["string", "null"], "format": "uri" },
          "iosUrl": { "type": ["string", "null"], "format": "uri" },
          "androidUrl": { "type": ["string", "null"], "format": "uri" },
          "iosFallbackUrl": { "type": ["string", "null"], "format": "uri" },
          "androidFallbackUrl": { "type": ["string", "null"], "format": "uri" },
          "parameters": { "type": ["object", "null"], "additionalProperties": true },
          "metadata": { "type": ["object", "null"], "additionalProperties": true },
          "allowQueryPassthrough": { "type": "boolean" }
        }
      },
      "CreateLinkRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["type"],
        "properties": {
          "type": { "type": "string", "enum": ["unified", "dynamic"] },
          "slug": { "type": "string", "minLength": 1, "maxLength": 255 },
          "name": { "type": "string", "maxLength": 255 },
          "externalId": { "type": "string", "minLength": 1, "maxLength": 255, "pattern": "^\\S+$" },
          "domain": { "type": "string", "examples": ["example.shared.ly"] },
          "fallbackUrl": { "type": "string", "format": "uri" },
          "iosUrl": { "type": "string", "format": "uri" },
          "androidUrl": { "type": "string", "format": "uri" },
          "iosFallbackUrl": { "type": "string", "format": "uri" },
          "androidFallbackUrl": { "type": "string", "format": "uri" },
          "parameters": { "type": "object", "additionalProperties": true },
          "metadata": { "type": "object", "additionalProperties": true },
          "allowQueryPassthrough": { "type": "boolean", "default": false }
        }
      },
      "Link": {
        "allOf": [
          { "$ref": "#/components/schemas/ResolvedLink" },
          {
            "type": "object",
            "required": ["shortUrl"],
            "properties": {
              "shortUrl": { "type": "string", "format": "uri" },
              "externalId": { "type": ["string", "null"] },
              "createdAt": { "type": "string", "format": "date-time" },
              "updatedAt": { "type": "string", "format": "date-time" }
            }
          }
        ]
      },
      "BootstrapRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/TrackInstallationRequest"
          },
          {
            "type": "object",
            "properties": {
              "networkType": {
                "type": "string",
                "description": "Network type, for example wifi or cellular.",
                "examples": [
                  "wifi"
                ]
              },
              "deviceOrientation": {
                "type": "string",
                "examples": [
                  "portrait"
                ]
              },
              "batteryLevel": {
                "type": "number",
                "minimum": 0,
                "maximum": 1,
                "description": "Battery level from 0 to 1.",
                "examples": [
                  0.75
                ]
              },
              "isCharging": {
                "type": "boolean"
              },
              "metadata": {
                "type": "object",
                "additionalProperties": true,
                "description": "Additional session metadata."
              }
            }
          }
        ]
      },
      "BootstrapResponse": {
        "type": "object",
        "required": [
          "success",
          "installationId",
          "sessionId",
          "sessionCreated",
          "isReinstall"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "installationId": {
            "type": "string"
          },
          "installationToken": {
            "type": [
              "string",
              "null"
            ],
            "description": "Signed token valid for 180 days. Identifies the installation; it is not an authentication credential."
          },
          "sessionId": {
            "type": "string",
            "description": "Active session, created or reused on every plan."
          },
          "sessionCreated": {
            "type": "boolean"
          },
          "isReinstall": {
            "type": "boolean"
          },
          "previousInstallationId": {
            "type": "string",
            "description": "Present only when isReinstall is true."
          },
          "reinstallDetectedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Present only when isReinstall is true."
          },
          "persistentDeviceId": {
            "type": "string",
            "description": "Present when a persistent device identifier is known."
          }
        }
      },
      "DeferredMatchRequest": {
        "type": "object",
        "required": [
          "fingerprint"
        ],
        "properties": {
          "clickId": {
            "type": "string",
            "description": "Click identifier from the install referrer, when available."
          },
          "installationId": {
            "type": "string"
          },
          "fingerprint": {
            "type": "object",
            "description": "Device fingerprint captured on first launch. Required even when `clickId` is sent: the server reads it to build the deep link after a match.",
            "properties": {
              "os": {
                "type": "string"
              },
              "screenResolution": {
                "type": "string",
                "examples": [
                  "1170x2532"
                ]
              },
              "timezone": {
                "type": "string",
                "examples": [
                  "Europe/Berlin"
                ]
              },
              "language": {
                "type": "string",
                "examples": [
                  "en-US"
                ]
              }
            }
          }
        }
      },
      "DeferredMatchResponse": {
        "type": "object",
        "required": [
          "success"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "matchType": {
            "type": "string",
            "enum": [
              "deterministic",
              "fingerprint"
            ]
          },
          "clickId": {
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "deepLink": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "slug": {
                "type": "string"
              },
              "parameters": {},
              "iosUrl": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "androidUrl": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "fallbackUrl": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "error": {
            "type": "string",
            "description": "Present when success is false, including the Free-plan upgrade message."
          }
        }
      },
      "TrackInstallationRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["installationId"],
        "properties": {
          "installationId": { "type": "string", "minLength": 1, "maxLength": 255, "pattern": ".*\\S.*" },
          "persistentDeviceId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "pattern": ".*\\S.*",
            "description": "Stable device identifier used to recognize the same device after reinstall when the platform preserves it."
          },
          "deviceId": { "type": "string" },
          "deviceModel": { "type": "string" },
          "deviceManufacturer": { "type": "string" },
          "osName": { "type": "string" },
          "osVersion": { "type": "string" },
          "appVersion": { "type": "string" },
          "appBuild": { "type": "string" },
          "language": { "type": "string" },
          "timezone": { "type": "string" },
          "networkType": { "type": "string" },
          "deviceOrientation": { "type": "string" },
          "batteryLevel": { "type": "number", "minimum": 0, "maximum": 1 },
          "isCharging": { "type": "boolean" },
          "metadata": { "type": "object", "additionalProperties": true }
        }
      },
      "TrackInstallationResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["success", "installationId", "isNew"],
        "properties": {
          "success": { "type": "boolean", "const": true },
          "installationId": { "type": "string", "format": "uuid" },
          "isNew": { "type": "boolean" },
          "installationToken": { "type": "string" }
        }
      },
      "StartSessionRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["installationId"],
        "properties": {
          "installationId": { "type": "string", "minLength": 1 },
          "networkType": { "type": "string" },
          "deviceOrientation": { "type": "string" },
          "batteryLevel": { "type": "number", "minimum": 0, "maximum": 1 },
          "isCharging": { "type": "boolean" },
          "metadata": { "type": "object", "additionalProperties": true }
        }
      },
      "StartSessionResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["success", "sessionId"],
        "properties": {
          "success": { "type": "boolean", "const": true },
          "sessionId": { "type": "string", "format": "uuid" }
        }
      },
      "SuccessResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["success"],
        "properties": {
          "success": { "type": "boolean" }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": ["type", "title", "status", "detail", "instance", "code", "statusCode", "message", "error"],
        "properties": {
          "type": { "type": "string", "format": "uri-reference" },
          "title": { "type": "string" },
          "status": { "type": "integer", "minimum": 400, "maximum": 599 },
          "detail": { "type": "string" },
          "instance": { "type": "string", "format": "uri-reference" },
          "code": {
            "type": "string",
            "pattern": "^[A-Z][A-Z0-9_]*$",
            "examples": ["VALIDATION_ERROR", "NOT_FOUND", "RATE_LIMIT_EXCEEDED"]
          },
          "statusCode": { "type": "integer", "minimum": 400, "maximum": 599 },
          "message": { "type": ["string", "array"], "items": { "type": "string" } },
          "error": { "type": "string" },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["detail"],
              "properties": { "detail": { "type": "string" } }
            }
          },
          "violated-policies": { "type": "array", "items": { "type": "string" } }
        }
      }
    }
  }
}
