{
  "components": {
    "headers": {
      "X-Quota-Limit": {
        "schema": {
          "type": "integer"
        }
      },
      "X-Quota-Remaining": {
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Limit": {
        "description": "req/min",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining": {
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Reset": {
        "description": "s",
        "schema": {
          "type": "integer"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "description": "Invalid parameters."
      },
      "Forbidden": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "description": "Account suspended, no plan for this API, or IP not allowed."
      },
      "NotFound": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "description": "Resource not found."
      },
      "RateLimited": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "description": "Per-minute limit or monthly quota reached. See Retry-After."
      },
      "Unauthorized": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "description": "Missing, invalid, expired or wrong-product key."
      },
      "Unavailable": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "description": "API under maintenance or overloaded."
      }
    },
    "schemas": {
      "Error": {
        "properties": {
          "error": {
            "properties": {
              "code": {
                "examples": [
                  "rate_limited"
                ],
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ],
            "type": "object"
          }
        },
        "required": [
          "error"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "apiKeyHeader": {
        "in": "header",
        "name": "X-API-Key",
        "type": "apiKey"
      },
      "bearerAuth": {
        "bearerFormat": "flye_sk_... | flye_test_...",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "externalDocs": {
    "url": "https://flye.win/docs"
  },
  "info": {
    "contact": {
      "name": "flye.win",
      "url": "https://flye.win/docs"
    },
    "description": "flye.win HTTP APIs. One key works for every API; each one has plans with per-minute and monthly limits. Test keys (flye_test_...) answer with the examples in this spec, without using quota.",
    "termsOfService": "https://flye.win/terms",
    "title": "flye.win APIs",
    "version": "1"
  },
  "openapi": "3.1.0",
  "paths": {
    "/cdn/images/{id}": {
      "delete": {
        "description": "Deletes the image and frees the space right away. The link stops working within moments.",
        "operationId": "cdnDeleteImage",
        "parameters": [
          {
            "description": "Image id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "deleted": true,
                  "id": "6f1c2a9e-4b7d-4e1a-9c3f-2d8b7a6e5f40"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "Delete an image",
        "tags": [
          "cdn"
        ]
      },
      "get": {
        "description": "Returns one of your images by the id returned on upload.",
        "operationId": "cdnGetImage",
        "parameters": [
          {
            "description": "Image id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "content_type": "image/jpeg",
                  "created_at": "2026-11-02T13:30:00Z",
                  "filename": "1743580800000000000.jpg",
                  "folder": "produtos",
                  "id": "6f1c2a9e-4b7d-4e1a-9c3f-2d8b7a6e5f40",
                  "original_name": "tenis-azul.jpg",
                  "project": "loja",
                  "size": 204800,
                  "url": "https://cdn.flye.win/images/fw_9c41d2e07ab3f5168e2d/produtos/1743580800000000000.jpg"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "Image details",
        "tags": [
          "cdn"
        ]
      }
    },
    "/cdn/projects": {
      "get": {
        "description": "Lists your account's projects, with the image count and storage used by each.",
        "operationId": "cdnListProjects",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "projects": [
                    {
                      "bytes": 52428800,
                      "created_at": "2026-10-01T12:00:00Z",
                      "images": 128,
                      "name": "loja"
                    }
                  ]
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "List projects",
        "tags": [
          "cdn"
        ]
      },
      "post": {
        "description": "Creates an empty project. Optional: uploading already creates the project when it doesn't exist.",
        "operationId": "cdnCreateProject",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "name": "loja"
              },
              "schema": {
                "properties": {
                  "name": {
                    "description": "Project name.",
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "bytes": 0,
                  "created_at": "2026-11-02T13:30:00Z",
                  "images": 0,
                  "name": "loja"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "Create a project",
        "tags": [
          "cdn"
        ]
      }
    },
    "/cdn/projects/{project}": {
      "delete": {
        "description": "Deletes the project with all its images and frees the space right away. This can't be undone.",
        "operationId": "cdnDeleteProject",
        "parameters": [
          {
            "description": "Project name.",
            "in": "path",
            "name": "project",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "deleted": true,
                  "images": 128,
                  "project": "loja"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "Delete a project",
        "tags": [
          "cdn"
        ]
      },
      "get": {
        "description": "Lists the project's images, newest first, and the folders it has.",
        "operationId": "cdnGetProject",
        "parameters": [
          {
            "description": "Project name.",
            "in": "path",
            "name": "project",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only this folder's images. Without it, every image in the project. Use / for only those outside folders.",
            "in": "query",
            "name": "folder",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Page, starting at 1.",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Items per page, 1 to 100. Defaults to 20.",
            "in": "query",
            "name": "per_page",
            "required": false,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "folders": [
                    {
                      "images": 96,
                      "name": "produtos"
                    }
                  ],
                  "images": [
                    {
                      "content_type": "image/jpeg",
                      "created_at": "2026-11-02T13:30:00Z",
                      "filename": "1743580800000000000.jpg",
                      "folder": "produtos",
                      "id": "6f1c2a9e-4b7d-4e1a-9c3f-2d8b7a6e5f40",
                      "original_name": "tenis-azul.jpg",
                      "project": "loja",
                      "size": 204800,
                      "url": "https://cdn.flye.win/images/fw_9c41d2e07ab3f5168e2d/produtos/1743580800000000000.jpg"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "per_page": 20,
                    "total": 96,
                    "total_pages": 5
                  },
                  "project": "loja"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "List images",
        "tags": [
          "cdn"
        ]
      }
    },
    "/cdn/upload": {
      "post": {
        "description": "Uploads one image as multipart/form-data. The project is created the first time you use it. Accepts jpg, jpeg, png, gif, webp, svg, up to your plan's per-file limit. The type is checked from the file's content, and SVG with scripts or external links is rejected.",
        "operationId": "cdnUpload",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "properties": {
                  "folder": {
                    "description": "Folder inside the project, optional, with the same rules as the name.",
                    "type": "string"
                  },
                  "image": {
                    "description": "The file. Also accepted under the name file.",
                    "format": "binary",
                    "type": "string"
                  },
                  "project": {
                    "description": "Project name: letters, numbers, - and _, up to 48 characters. Uppercase becomes lowercase.",
                    "type": "string"
                  }
                },
                "required": [
                  "image",
                  "project"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "content_type": "image/jpeg",
                  "created_at": "2026-11-02T13:30:00Z",
                  "filename": "1743580800000000000.jpg",
                  "folder": "produtos",
                  "id": "6f1c2a9e-4b7d-4e1a-9c3f-2d8b7a6e5f40",
                  "original_name": "tenis-azul.jpg",
                  "project": "loja",
                  "size": 204800,
                  "url": "https://cdn.flye.win/images/fw_9c41d2e07ab3f5168e2d/produtos/1743580800000000000.jpg"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "Upload an image",
        "tags": [
          "cdn"
        ]
      }
    },
    "/cdn/usage": {
      "get": {
        "description": "Shows the storage used, your plan's limits and the largest file accepted. A null limit means unlimited.",
        "operationId": "cdnGetUsage",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "images": 128,
                  "max_file_bytes": 20971520,
                  "projects": {
                    "limit": 5,
                    "used": 1
                  },
                  "storage": {
                    "limit_bytes": 5368709120,
                    "used_bytes": 52428800
                  }
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "Storage and limits",
        "tags": [
          "cdn"
        ]
      }
    },
    "/stickers/packs": {
      "get": {
        "description": "Lists the packs found for the term, with a cover sticker, so you can build a picker.",
        "operationId": "stickersListPacks",
        "parameters": [
          {
            "description": "Search term, 2 to 80 characters.",
            "example": "gato",
            "in": "query",
            "name": "q",
            "required": true,
            "schema": {
              "examples": [
                "gato"
              ],
              "type": "string"
            }
          },
          {
            "description": "Scale plan: identifies the user on your platform, so the limit applies per user and not to the account. Use a stable id, preferably a hash.",
            "in": "header",
            "name": "X-End-User-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Longest wait for a term never searched before, 0 to 15000 ms. Past that, the response returns right away with pending=true and the search continues: repeat the call shortly. Without it, waits for the result.",
            "example": "300",
            "in": "query",
            "name": "max_wait_ms",
            "required": false,
            "schema": {
              "examples": [
                "300"
              ],
              "type": "integer"
            }
          },
          {
            "description": "Packs per page, 1 to 20. Defaults to 10.",
            "example": "5",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "examples": [
                "5"
              ],
              "type": "integer"
            }
          },
          {
            "description": "Page, starting at 1.",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "all, animated or static. Defaults to all.",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "packs": [
                    {
                      "animated": true,
                      "author": "Ana",
                      "count": 30,
                      "cover": "https://flye.win/media/stickers/8e1f0c3ab94d27f6a5c1e08d7b3f4a12.webp",
                      "id": "pk_3f9a1c7e2b8d4a60c1e5",
                      "name": "Gatos engraçados"
                    }
                  ],
                  "page": 1,
                  "query": "gato",
                  "total": 12
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "List packs",
        "tags": [
          "stickers"
        ]
      }
    },
    "/stickers/packs/{id}": {
      "get": {
        "description": "Returns every sticker in a pack by its id.",
        "operationId": "stickersGetPack",
        "parameters": [
          {
            "description": "Pack id, from /search or /packs.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "pack": {
                    "animated": true,
                    "author": "Ana",
                    "count": 30,
                    "id": "pk_3f9a1c7e2b8d4a60c1e5",
                    "name": "Gatos engraçados"
                  },
                  "stickers": [
                    {
                      "animated": true,
                      "format": "webp",
                      "id": "8e1f0c3ab94d27f6a5c1e08d7b3f4a12",
                      "url": "https://flye.win/media/stickers/8e1f0c3ab94d27f6a5c1e08d7b3f4a12.webp"
                    }
                  ]
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "Stickers in a pack",
        "tags": [
          "stickers"
        ]
      }
    },
    "/stickers/search": {
      "get": {
        "description": "Returns the most relevant pack for the term, with a link for each sticker. With rotate=true, each call returns the next pack, so bots don't repeat the same result. A term never searched before may come right away with partial=true, with what we already have, while the full search finishes.",
        "operationId": "stickersSearch",
        "parameters": [
          {
            "description": "Search term, 2 to 80 characters. Without it, the response has 30 featured stickers, drawn on every call, with trending=true.",
            "example": "gato",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "examples": [
                "gato"
              ],
              "type": "string"
            }
          },
          {
            "description": "Scale plan: identifies the user on your platform, so the limit applies per user and not to the account. Use a stable id, preferably a hash.",
            "in": "header",
            "name": "X-End-User-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Longest wait for a term never searched before, 0 to 15000 ms. Past that, the response returns right away with pending=true and the search continues: repeat the call shortly. Without it, waits for the result.",
            "example": "300",
            "in": "query",
            "name": "max_wait_ms",
            "required": false,
            "schema": {
              "examples": [
                "300"
              ],
              "type": "integer"
            }
          },
          {
            "description": "Stickers per response, 1 to 30. Defaults to 30.",
            "example": "10",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "examples": [
                "10"
              ],
              "type": "integer"
            }
          },
          {
            "description": "all, animated or static. Defaults to all.",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Pack position in the ranking, starting at 1. Defaults to 1.",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "true returns the next pack on each call from this account. Ignores page.",
            "in": "query",
            "name": "rotate",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "pack": {
                    "animated": true,
                    "author": "Ana",
                    "count": 30,
                    "id": "pk_3f9a1c7e2b8d4a60c1e5",
                    "name": "Gatos engraçados"
                  },
                  "query": "gato",
                  "stickers": [
                    {
                      "animated": true,
                      "format": "webp",
                      "id": "8e1f0c3ab94d27f6a5c1e08d7b3f4a12",
                      "url": "https://flye.win/media/stickers/8e1f0c3ab94d27f6a5c1e08d7b3f4a12.webp"
                    }
                  ],
                  "total_packs": 12
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "Search stickers",
        "tags": [
          "stickers"
        ]
      }
    },
    "/utils/base64": {
      "post": {
        "description": "Converts text to and from standard base64 (RFC 4648).",
        "operationId": "utilsBase64",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "mode": "encode",
                "text": "hello, world"
              },
              "schema": {
                "properties": {
                  "mode": {
                    "description": "encode or decode. Defaults to encode.",
                    "type": "string"
                  },
                  "text": {
                    "description": "Content to convert.",
                    "type": "string"
                  }
                },
                "required": [
                  "text"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "mode": "encode",
                  "result": "aGVsbG8sIHdvcmxk"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "Encode / decode base64",
        "tags": [
          "utils"
        ]
      }
    },
    "/utils/hash": {
      "get": {
        "description": "Hashes the given text and returns it as hex.",
        "operationId": "utilsHash",
        "parameters": [
          {
            "description": "Input text (up to 64 KB).",
            "example": "flye",
            "in": "query",
            "name": "text",
            "required": true,
            "schema": {
              "examples": [
                "flye"
              ],
              "type": "string"
            }
          },
          {
            "description": "md5, sha1, sha256 or sha512. Defaults to sha256.",
            "example": "sha256",
            "in": "query",
            "name": "algo",
            "required": false,
            "schema": {
              "examples": [
                "sha256"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "algo": "sha256",
                  "hex": "9a5c3b4f1f8e0d6c…"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "Compute a hash",
        "tags": [
          "utils"
        ]
      }
    },
    "/utils/ip": {
      "get": {
        "description": "Returns the IP and user agent your request reached the platform with.",
        "operationId": "utilsIp",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "ip": "203.0.113.24",
                  "user_agent": "curl/8.7.1"
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "Source IP",
        "tags": [
          "utils"
        ]
      }
    },
    "/utils/uuid": {
      "get": {
        "description": "Generates 1 to 100 UUIDs. Version 7 sorts by time, which suits primary keys.",
        "operationId": "utilsUuid",
        "parameters": [
          {
            "description": "How many, from 1 to 100. Defaults to 1.",
            "example": "2",
            "in": "query",
            "name": "count",
            "required": false,
            "schema": {
              "examples": [
                "2"
              ],
              "type": "integer"
            }
          },
          {
            "description": "4 (random) or 7 (time-ordered). Defaults to 4.",
            "example": "7",
            "in": "query",
            "name": "version",
            "required": false,
            "schema": {
              "examples": [
                "7"
              ],
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "uuids": [
                    "019a3c1e-7b2d-7c41-9f0e-5d8a21c4b6e3",
                    "019a3c1e-7b2d-7f88-a1c2-0e93b7d45f12"
                  ],
                  "version": 7
                }
              }
            },
            "description": "OK",
            "headers": {
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "summary": "Generate UUIDs",
        "tags": [
          "utils"
        ]
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyHeader": []
    }
  ],
  "servers": [
    {
      "url": "https://flye.win/v1"
    }
  ],
  "tags": [
    {
      "description": "Stickers — Search stickers and animated GIFs, with ready-to-use links.",
      "externalDocs": {
        "url": "https://flye.win/apis/stickers"
      },
      "name": "stickers"
    },
    {
      "description": "CDN — Image hosting with public links, organized in projects and folders.",
      "externalDocs": {
        "url": "https://flye.win/apis/cdn"
      },
      "name": "cdn"
    },
    {
      "description": "Utils — UUIDs, hashes, base64 and IP inspection in one call.",
      "externalDocs": {
        "url": "https://flye.win/apis/utils"
      },
      "name": "utils"
    }
  ]
}