{
  "openapi": "3.1.0",
  "info": {
    "title": "GetInSaver Public Media API",
    "summary": "Resolve supported public social-media URLs into normalized media results.",
    "description": "A commercial REST API for supported publicly accessible Instagram, TikTok, X/Twitter, Pinterest and Telegram media workflows. The API does not bypass privacy, authentication or rights controls. Failed resolutions consume zero credits.",
    "version": "1.0.0",
    "contact": {
      "name": "GetInSaver Developers",
      "url": "https://developers.getinsaver.com/docs",
      "email": "support@getinsaver.com"
    },
    "termsOfService": "https://developers.getinsaver.com/terms"
  },
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "servers": [
    { "url": "https://developers.getinsaver.com", "description": "Production" }
  ],
  "tags": [
    { "name": "Media", "description": "Resolve supported public media URLs." }
  ],
  "paths": {
    "/v1/resolve": {
      "post": {
        "operationId": "resolvePublicMedia",
        "summary": "Resolve a public media URL",
        "description": "Validates the URL against the selected service, reserves up to `max_results × service multiplier` credits, resolves the public media, and settles only the items returned. Failed requests are refunded in full.",
        "tags": ["Media"],
        "security": [{ "bearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ResolveRequest" },
              "examples": {
                "instagramReel": {
                  "summary": "Instagram Reel",
                  "value": {
                    "service": "instagram",
                    "url": "https://www.instagram.com/reel/SHORTCODE/",
                    "max_results": 10
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The public media URL was resolved successfully.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ResolveResponse" },
                "examples": {
                  "video": {
                    "value": {
                      "ok": true,
                      "service": "instagram",
                      "source_url": "https://www.instagram.com/reel/SHORTCODE/",
                      "item_count": 1,
                      "items": [{ "type": "video", "url": "https://cdn.example/media.mp4" }],
                      "metadata": { "title": null, "author": "creator", "caption": null },
                      "request_id": "39a3bff5-0000-4000-8000-000000000000",
                      "credits_used": 1
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/InsufficientCredits" },
          "422": { "$ref": "#/components/responses/UnprocessableMedia" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/UpstreamFailure" },
          "504": { "$ref": "#/components/responses/UpstreamTimeout" }
        },
        "x-credit-metering": {
          "reservation": "max_results × service multiplier",
          "settlement": "returned item_count × service multiplier",
          "failedRequests": 0
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "gis_live_*",
        "description": "Create a server-side API key in the GetInSaver dashboard. Never expose it in browser or mobile-client code."
      }
    },
    "schemas": {
      "ServiceId": {
        "type": "string",
        "enum": ["instagram", "instagram-story", "instagram-highlight", "tiktok", "x", "pinterest", "telegram"],
        "description": "Service identifier. Instagram Posts/Reels, Stories and Highlights use distinct IDs and URL rules."
      },
      "ResolveRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["service", "url"],
        "properties": {
          "service": { "$ref": "#/components/schemas/ServiceId" },
          "url": { "type": "string", "format": "uri", "maxLength": 2048, "description": "A supported publicly accessible HTTP(S) media URL." },
          "max_results": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10, "description": "Maximum items to return and the basis of the temporary credit reservation." }
        }
      },
      "MediaItem": {
        "type": "object",
        "additionalProperties": false,
        "required": ["type", "url"],
        "properties": {
          "type": { "type": "string", "enum": ["video", "image", "audio"] },
          "url": { "type": "string", "format": "uri", "description": "Resolved media URL. Treat this URL as temporary and consume it promptly." }
        }
      },
      "MediaMetadata": {
        "type": "object",
        "additionalProperties": false,
        "required": ["title", "author", "caption"],
        "properties": {
          "title": { "type": ["string", "null"] },
          "author": { "type": ["string", "null"] },
          "caption": { "type": ["string", "null"] }
        }
      },
      "ResolveResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["ok", "service", "source_url", "item_count", "items", "metadata", "request_id", "credits_used"],
        "properties": {
          "ok": { "type": "boolean", "const": true },
          "service": { "$ref": "#/components/schemas/ServiceId" },
          "source_url": { "type": "string", "format": "uri" },
          "item_count": { "type": "integer", "minimum": 1, "maximum": 20 },
          "items": { "type": "array", "minItems": 1, "maxItems": 20, "items": { "$ref": "#/components/schemas/MediaItem" } },
          "metadata": { "$ref": "#/components/schemas/MediaMetadata" },
          "request_id": { "type": "string", "format": "uuid", "description": "Usage-ledger ID for support and reconciliation." },
          "credits_used": { "type": "integer", "minimum": 1 }
        }
      },
      "Error": {
        "type": "object",
        "additionalProperties": true,
        "required": ["error", "code", "message"],
        "properties": {
          "error": { "type": "boolean", "const": true },
          "code": {
            "type": "string",
            "examples": ["URL_INVALID", "API_KEY_INVALID", "INSUFFICIENT_CREDITS", "MEDIA_NOT_FOUND", "RATE_LIMITED"]
          },
          "message": { "type": "string" }
        }
      }
    },
    "responses": {
      "BadRequest": { "description": "Unsupported service or invalid URL/body (`SERVICE_UNSUPPORTED`, `URL_INVALID`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Unauthorized": { "description": "Missing, invalid, revoked, inactive or unverified API key (`API_KEY_INVALID`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "InsufficientCredits": { "description": "The account cannot reserve the requested maximum results (`INSUFFICIENT_CREDITS`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "UnprocessableMedia": { "description": "The URL is valid but no supported public media could be resolved (`MEDIA_NOT_FOUND`, `UPSTREAM_REJECTED`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "RateLimited": { "description": "Gateway rate limit exceeded (`RATE_LIMITED`). Default: 120 requests/minute/API key.", "headers": { "RateLimit": { "description": "Current rate-limit policy and reset information.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "UpstreamFailure": { "description": "The media provider returned an invalid response or upstream error (`UPSTREAM_INVALID_RESPONSE`, `UPSTREAM_ERROR`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "UpstreamTimeout": { "description": "The upstream processing window elapsed (`UPSTREAM_TIMEOUT`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  },
  "x-service-credit-multipliers": {
    "instagram": 1,
    "instagram-story": 2,
    "instagram-highlight": 2,
    "tiktok": 1,
    "x": 1,
    "pinterest": 1,
    "telegram": 2
  }
}
