{
  "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": "Upload images up to 100 MB and get a public link ready for your site, app or bot. Organize them in projects and folders, track your storage and manage everything from the dashboard too. Each project is yours alone: other accounts can't list, reach through the API or delete what you uploaded.",
    "termsOfService": "https://flye.win/terms",
    "title": "flye.win CDN API",
    "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"
        ]
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyHeader": []
    }
  ],
  "servers": [
    {
      "url": "https://flye.win/v1"
    }
  ],
  "tags": [
    {
      "description": "CDN — Image hosting with public links, organized in projects and folders.",
      "externalDocs": {
        "url": "https://flye.win/apis/cdn"
      },
      "name": "cdn"
    }
  ]
}