{
  "openapi": "3.1.0",
  "info": {
    "title": "FILELINK.PRO API",
    "version": "1.0.0",
    "description": "Send encrypted files from your own software. With the File Link Pro API, your app can upload a file, share it through a private link, and keep track of every transfer in your Premium workspace.\n\n## How a transfer works\n\n1. **Encrypt.** Your app encrypts the file with libsodium, so File Link Pro stores encrypted bytes from start to finish.\n2. **Upload.** Create the transfer, upload the encrypted file, then finalize it, all through `POST /api/v1/transfers`.\n3. **Share.** Hand out the private link yourself, or have File Link Pro email it to recipients with `POST /api/v1/shares/{id}/notifications`.\n4. **Download.** Recipients open the link, and their browser decrypts the file as it downloads.\n5. **Manage.** Change the expiry or download limit, check email delivery, or revoke the transfer to delete its stored file.\n\nThe decryption key lives in your system and inside the private link. It goes out by email when you ask File Link Pro to send the link to a recipient.\n\n## What you can do\n\n- **Workspace:** check your usage, limits and pricing.\n- **Transfers:** list your transfers and create new ones.\n- **Sharing:** read a transfer's settings, change its expiry and download limit, or revoke it.\n- **Notifications:** email recipients their link and see whether it was delivered.\n- **API keys:** create, list and revoke workspace keys.\n- **Recipient downloads:** the public endpoints recipients use to fetch a file, with the link alone.\n\n## Access\n\nSend your workspace API key as a bearer token with every workspace request: `Authorization: Bearer flp_\u2026`. Create keys in your Premium dashboard and keep them on your server. A workspace can have 10 active keys.\n\n## Plan and limits\n\nPremium includes files up to 1 GB each and 10 GB of workspace storage, where 1 GB is 1,073,741,824 bytes. A workspace can have 3 uploads in progress at once and keep 200 transfer records. Uploads come with your subscription, which you buy and manage on the website. Larger one-off transfers are paid for separately, as the transfer lifecycle explains.\n\n## Good to know\n\n- Workspace times are Unix milliseconds. A recipient's `expiresAt` is an ISO 8601 date.\n- Errors come back as JSON with an `error` field. 401 means the key is missing, 403 means access is denied, 400 means the request needs fixing, and 429 means slow down and try again shortly.\n- Each create call starts a new transfer, so check the result before you try again. Uploading a part, finalizing and sending notifications are safe to retry.\n\n## Get started\n\nFollow the [upload guide](/api-docs) and the [working Node.js example](/examples/upload.mjs).",
    "contact": {
      "name": "File Link Pro",
      "email": "hello@filelink.pro",
      "url": "https://filelink.pro"
    },
    "termsOfService": "https://filelink.pro/terms"
  },
  "servers": [
    {
      "url": "https://filelink.pro",
      "description": "Production \u2014 requests affect real files and accounts"
    }
  ],
  "security": [
    {
      "WorkspaceApiKey": []
    }
  ],
  "tags": [
    {
      "name": "Workspace"
    },
    {
      "name": "Transfers"
    },
    {
      "name": "Sharing"
    },
    {
      "name": "Notifications"
    },
    {
      "name": "API keys"
    },
    {
      "name": "Recipient downloads"
    }
  ],
  "paths": {
    "/api/v1/account": {
      "get": {
        "tags": [
          "Workspace"
        ],
        "operationId": "getAccount",
        "summary": "Read usage, limits and member pricing",
        "responses": {
          "200": {
            "description": "Current workspace allowance and usage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "401": {
            "description": "Missing workspace API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Invalid or revoked key, inactive Premium subscription, access denied or resource unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/transfers": {
      "get": {
        "tags": [
          "Transfers"
        ],
        "operationId": "listTransfers",
        "summary": "List workspace transfers",
        "description": "Returns non-pending transfers from the newest 201 records, newest first. No pagination. Check expiresAt: an expired record may retain state active.",
        "responses": {
          "200": {
            "description": "Transfer records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransferList"
                }
              }
            }
          },
          "401": {
            "description": "Missing workspace API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Invalid or revoked key, inactive Premium subscription, access denied or resource unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Transfers"
        ],
        "operationId": "operateTransfer",
        "summary": "Create, upload and finalize an encrypted transfer",
        "description": "Choose the request schema using operation. All calls require the workspace bearer key; operations after create also require the returned transfer capability. Body limit: 8,192 characters. Server-to-server requests should omit Origin; if present it must match the API origin.\n\nIncluded flow: create with usePremium=true \u2192 encrypt locally \u2192 start \u2192 part + PUT encrypted bytes to R2 (repeat) \u2192 complete. Use status for progress. Use a fresh 32-byte libsodium secretstream XChaCha20-Poly1305 key and 24-byte header; unpadded base64url. Plaintext chunks are 8,388,608 bytes; every encrypted chunk adds 17 bytes. TAG_MESSAGE for intermediate chunks, TAG_FINAL for the final chunk. The key belongs only in the recipient URL fragment: https://filelink.pro/d/{publicId}#key={key}.\n\nReservations expire after 24 hours. Three pending included reservations and 200 transfer records maximum. Repeating create makes a new reservation. Retry a part with identical ciphertext; completing with the same header is safe. Never mix encryption streams.\n\nOptional paid flow: usePremium=false \u2192 checkout \u2192 collect payment \u2192 status confirms paid \u2192 upload. A separate inline payment integration is required; contact hello@filelink.pro for File Link Pro\u2019s matching publishable key. No Stripe SDK is needed for included uploads. No automatic overage billing.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/CreateTransfer"
                  },
                  {
                    "$ref": "#/components/schemas/StartTransfer"
                  },
                  {
                    "$ref": "#/components/schemas/UploadPart"
                  },
                  {
                    "$ref": "#/components/schemas/CompleteTransfer"
                  },
                  {
                    "$ref": "#/components/schemas/TransferStatusRequest"
                  },
                  {
                    "$ref": "#/components/schemas/TransferCheckoutRequest"
                  }
                ],
                "discriminator": {
                  "propertyName": "operation",
                  "mapping": {
                    "create": "#/components/schemas/CreateTransfer",
                    "start": "#/components/schemas/StartTransfer",
                    "part": "#/components/schemas/UploadPart",
                    "complete": "#/components/schemas/CompleteTransfer",
                    "status": "#/components/schemas/TransferStatusRequest",
                    "checkout": "#/components/schemas/TransferCheckoutRequest"
                  }
                }
              },
              "examples": {
                "included": {
                  "summary": "Create an included Premium transfer",
                  "value": {
                    "operation": "create",
                    "name": "presentation.pdf",
                    "size": 5242880,
                    "mime": "application/pdf",
                    "days": 7,
                    "usePremium": true,
                    "maxDownloads": 10
                  }
                },
                "status": {
                  "summary": "Check a transfer",
                  "value": {
                    "operation": "status",
                    "publicId": "l_0123456789abcdef0123456789abcdef",
                    "token": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Response depends on operation: start \u2192 chunkSize; part \u2192 url; complete \u2192 publicId; status \u2192 transfer state; checkout \u2192 clientSecret and amount.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/StartedTransfer"
                    },
                    {
                      "$ref": "#/components/schemas/UploadPartUrl"
                    },
                    {
                      "$ref": "#/components/schemas/CompletedTransfer"
                    },
                    {
                      "$ref": "#/components/schemas/TransferStatus"
                    },
                    {
                      "$ref": "#/components/schemas/TransferCheckout"
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "create: new reservation and its private capability.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedTransfer"
                }
              }
            }
          },
          "400": {
            "description": "Invalid operation or fields, quota exceeded, unavailable transfer/settings/payment, or upload failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing workspace API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Invalid or revoked key, inactive Premium subscription, access denied or resource unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the indicated delay.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Seconds before retry.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "503": {
            "description": "One-off payments are not configured.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/shares/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Public l_ identifier or internal transfer ID owned by this workspace.",
          "schema": {
            "type": "string",
            "minLength": 1
          }
        }
      ],
      "get": {
        "tags": [
          "Sharing"
        ],
        "operationId": "getShare",
        "summary": "Read file metadata and sharing settings",
        "responses": {
          "200": {
            "description": "Owned transfer details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Share"
                }
              }
            }
          },
          "401": {
            "description": "Missing workspace API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Invalid or revoked key, inactive Premium subscription, access denied or resource unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Sharing"
        ],
        "operationId": "updateShareSettings",
        "summary": "Update expiry and download cap",
        "description": "Only active, unexpired stream transfers can be updated. Expiry is measured from initial activation, not from this request. One-off transfers must retain seven days. Body limit: 4,096 characters. Empty bodies do not finalize uploads; use the complete operation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ShareSettings"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated access settings.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdatedSettings"
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or operation, denied subscription, unavailable settings or transfer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing workspace API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Sharing"
        ],
        "operationId": "revokeShare",
        "summary": "Revoke a transfer and remove its encrypted storage",
        "description": "Previously downloaded copies cannot be recalled.",
        "responses": {
          "200": {
            "description": "Access revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ok"
                }
              }
            }
          },
          "401": {
            "description": "Missing workspace API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Invalid or revoked key, inactive Premium subscription, access denied or resource unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/shares/{id}/notifications": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Public l_ identifier or internal transfer ID owned by this workspace.",
          "schema": {
            "type": "string",
            "minLength": 1
          }
        }
      ],
      "get": {
        "tags": [
          "Notifications"
        ],
        "operationId": "listNotifications",
        "summary": "Read recipient delivery status",
        "responses": {
          "200": {
            "description": "Notifications for this transfer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationList"
                }
              }
            }
          },
          "401": {
            "description": "Missing workspace API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Invalid or revoked key, inactive Premium subscription, access denied or resource unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Notifications"
        ],
        "operationId": "sendNotifications",
        "summary": "Queue recipient notification emails",
        "description": "Requires an active, unexpired transfer with downloads remaining. Up to 10 recipients per request, 30 per transfer, 100 per day and 10 per minute per account. Duplicate transfer/recipient pairs are not resent. Queued messages use provider retries. Supplying downloadKey explicitly sends the private link through File Link Pro and the email providers. Body limit: 4,096 characters. Validation and notification quota failures currently return 403.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendNotifications"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted or previously queued; not a guarantee of inbox delivery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedNotifications"
                }
              }
            }
          },
          "401": {
            "description": "Missing workspace API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Invalid or revoked key, inactive Premium subscription, access denied or resource unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/keys": {
      "get": {
        "tags": [
          "API keys"
        ],
        "operationId": "listApiKeys",
        "summary": "List keys without their secrets",
        "responses": {
          "200": {
            "description": "Workspace key records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyList"
                }
              }
            }
          },
          "401": {
            "description": "Missing workspace API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Invalid or revoked key, inactive Premium subscription, access denied or resource unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "API keys"
        ],
        "operationId": "createApiKey",
        "summary": "Create a workspace API key",
        "description": "Create the first key in the Premium dashboard. Up to ten active keys. Body limit: 512 characters. Validation and quota failures return 403.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiKey"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Store the token securely; it is returned only once.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedApiKey"
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            }
          },
          "401": {
            "description": "Missing workspace API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Invalid or revoked key, inactive Premium subscription, access denied or resource unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/keys/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Key ID returned by list or create; not the secret token."
        }
      ],
      "delete": {
        "tags": [
          "API keys"
        ],
        "operationId": "revokeApiKey",
        "summary": "Revoke an API key",
        "description": "Revocation takes effect immediately. A key may revoke itself.",
        "responses": {
          "200": {
            "description": "Key revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ok"
                }
              }
            }
          },
          "401": {
            "description": "Missing workspace API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Invalid or revoked key, inactive Premium subscription, access denied or resource unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/download/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "description": "Public transfer identifier.",
            "pattern": "^l_[a-f0-9]{32}$",
            "example": "l_0123456789abcdef0123456789abcdef"
          },
          "description": "Public identifier of an API-created stream transfer."
        }
      ],
      "get": {
        "tags": [
          "Recipient downloads"
        ],
        "operationId": "getDownloadInfo",
        "summary": "Read public recipient metadata",
        "security": [],
        "description": "Does not require an account or increment the download count. This reference describes API-created secretstream transfers.",
        "responses": {
          "200": {
            "description": "Available file metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DownloadInfo"
                }
              }
            }
          },
          "404": {
            "description": "not_found: missing, expired, revoked or unavailable transfer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "server_error: metadata service unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Recipient downloads"
        ],
        "operationId": "authorizeDownload",
        "summary": "Authorize one encrypted download",
        "security": [],
        "description": "Send an empty JSON object if no password is required. Increments the download count when access is authorized, not when saving finishes. Never send the private decryption key or URL fragment. Fetch blobUrl, then decrypt locally with libsodium secretstream using iv as the header. Read ciphertext in chunkSize + 17 byte chunks (except the shorter final chunk), verify every authentication tag and require TAG_FINAL with no missing or trailing data. Signed object URL is valid for 60 seconds.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DownloadRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authorized encrypted object URL and decryption metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DownloadAccess"
                }
              }
            }
          },
          "403": {
            "description": "wrong_password: incorrect or excessively long password.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: unavailable transfer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "unavailable: access cannot be granted or invalid JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the indicated delay.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Seconds before retry.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/shares/{id}/pass": {
      "post": {
        "operationId": "createFilePass",
        "tags": [
          "Sharing"
        ],
        "summary": "Create or refresh a branded Apple Wallet file pass",
        "description": "Requires a Premium workspace API key and ownership of the active transfer. Basic passes are free in the website. Explicitly providing downloadKey stores an encrypted copy for signing and automatic updates. Repeating a request for the same file and key returns the same pass identity; optional branding updates that pass. A different key is rejected. A pass contains the complete private URL and should be kept private.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Transfer ID or public streaming ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "downloadKey"
                ],
                "properties": {
                  "downloadKey": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{43}$",
                    "description": "Base64url decryption key from the private link fragment."
                  },
                  "sender": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60
                  },
                  "accent": {
                    "type": "string",
                    "pattern": "^#[0-9a-fA-F]{6}$"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signed .pkpass ZIP archive; save as File-Link.pkpass and open on iPhone. Includes Wallet registration and automatic refresh support.",
            "content": {
              "application/vnd.apple.pkpass": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "API key required",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Transfer access, subscription or key rejected",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "WorkspaceApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "flp_<64 hex characters>",
        "description": "A File Link Pro workspace API key, created in the Premium dashboard. All workspace endpoints verify an active Premium subscription. Keep keys in trusted server environments. Recipient downloads do not use this key."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable reason; except documented recipient error codes, do not rely on exact wording."
          }
        },
        "required": [
          "error"
        ]
      },
      "Ok": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          }
        },
        "required": [
          "ok"
        ]
      },
      "Account": {
        "type": "object",
        "properties": {
          "plan": {
            "type": "string",
            "const": "premium"
          },
          "maxFileBytes": {
            "type": "integer",
            "const": 1073741824
          },
          "maxStoredBytes": {
            "type": "integer",
            "const": 10737418240
          },
          "storedBytes": {
            "type": "integer",
            "description": "Active and pending included plaintext bytes.",
            "minimum": 0
          },
          "activeTransfers": {
            "type": "integer",
            "description": "Unexpired, non-revoked transfers including reservations.",
            "minimum": 0
          },
          "notificationRecipientsPerDay": {
            "type": "integer",
            "const": 100
          },
          "notificationRecipientsPerTransfer": {
            "type": "integer",
            "const": 30
          },
          "maxOneOffFileBytes": {
            "type": "integer",
            "const": 53687091200
          },
          "oneOffRatePerStartedGB": {
            "type": "integer",
            "const": 100
          },
          "currency": {
            "type": "string",
            "const": "usd"
          }
        },
        "required": [
          "plan",
          "maxFileBytes",
          "maxStoredBytes",
          "storedBytes",
          "activeTransfers",
          "notificationRecipientsPerDay",
          "notificationRecipientsPerTransfer",
          "maxOneOffFileBytes",
          "oneOffRatePerStartedGB",
          "currency"
        ]
      },
      "CreateTransfer": {
        "type": "object",
        "properties": {
          "operation": {
            "type": "string",
            "enum": [
              "create"
            ]
          },
          "name": {
            "type": "string",
            "description": "Original file name.",
            "minLength": 1,
            "maxLength": 240
          },
          "size": {
            "type": "integer",
            "description": "Plaintext bytes. 1 GB = 1,073,741,824 bytes.",
            "minimum": 1,
            "maximum": 53687091200
          },
          "mime": {
            "type": "string",
            "description": "Original MIME type.",
            "maxLength": 200
          },
          "usePremium": {
            "type": "boolean",
            "description": "Set true for included Premium storage (at most 1 GB per file). Explicitly set false to reserve a separately purchased transfer. No automatic charge.",
            "default": true
          },
          "days": {
            "type": "integer",
            "description": "Days from initial activation. Separately purchased transfers always use 7.",
            "enum": [
              1,
              7,
              30
            ],
            "default": 7
          },
          "password": {
            "type": "string",
            "description": "Optional recipient password; set only at creation.",
            "maxLength": 256,
            "writeOnly": true
          },
          "maxDownloads": {
            "type": "integer",
            "description": "Optional cap on authorized download requests.",
            "minimum": 1,
            "maximum": 1000
          }
        },
        "required": [
          "operation",
          "name",
          "size",
          "mime",
          "usePremium"
        ]
      },
      "CreatedTransfer": {
        "type": "object",
        "properties": {
          "publicId": {
            "type": "string",
            "description": "Public transfer identifier.",
            "pattern": "^l_[a-f0-9]{32}$",
            "example": "l_0123456789abcdef0123456789abcdef"
          },
          "token": {
            "type": "string",
            "description": "Transfer capability returned by create. Separate from the workspace API key. Keep private.",
            "pattern": "^[a-f0-9]{64}$"
          },
          "amount": {
            "type": "integer",
            "description": "Amount in USD cents.",
            "minimum": 0
          },
          "rate": {
            "type": "integer",
            "description": "USD cents per started binary GB.",
            "minimum": 0
          },
          "gigabytes": {
            "type": "integer",
            "description": "Plaintext size rounded up to a whole binary GB.",
            "minimum": 1,
            "maximum": 50
          },
          "included": {
            "type": "boolean"
          },
          "days": {
            "type": "integer",
            "description": "Days from initial activation. Separately purchased transfers always use 7.",
            "enum": [
              1,
              7,
              30
            ],
            "default": 7
          }
        },
        "required": [
          "publicId",
          "token",
          "amount",
          "rate",
          "gigabytes",
          "included",
          "days"
        ]
      },
      "StartTransfer": {
        "type": "object",
        "properties": {
          "operation": {
            "type": "string",
            "enum": [
              "start"
            ]
          },
          "publicId": {
            "type": "string",
            "description": "Public transfer identifier.",
            "pattern": "^l_[a-f0-9]{32}$",
            "example": "l_0123456789abcdef0123456789abcdef"
          },
          "token": {
            "type": "string",
            "description": "Transfer capability returned by create. Separate from the workspace API key. Keep private.",
            "pattern": "^[a-f0-9]{64}$",
            "writeOnly": true
          },
          "header": {
            "type": "string",
            "description": "Unpadded base64url-encoded 24-byte libsodium secretstream header. This is not the decryption key.",
            "pattern": "^[A-Za-z0-9_-]{32}$"
          }
        },
        "required": [
          "operation",
          "publicId",
          "token",
          "header"
        ]
      },
      "UploadPart": {
        "type": "object",
        "properties": {
          "operation": {
            "type": "string",
            "enum": [
              "part"
            ]
          },
          "publicId": {
            "type": "string",
            "description": "Public transfer identifier.",
            "pattern": "^l_[a-f0-9]{32}$",
            "example": "l_0123456789abcdef0123456789abcdef"
          },
          "token": {
            "type": "string",
            "description": "Transfer capability returned by create. Separate from the workspace API key. Keep private.",
            "pattern": "^[a-f0-9]{64}$",
            "writeOnly": true
          },
          "header": {
            "type": "string",
            "description": "Unpadded base64url-encoded 24-byte libsodium secretstream header. This is not the decryption key.",
            "pattern": "^[A-Za-z0-9_-]{32}$"
          },
          "part": {
            "type": "integer",
            "description": "One-based part number. Maximum ceil(plaintext bytes / 8,388,608).",
            "minimum": 1,
            "maximum": 6400
          }
        },
        "required": [
          "operation",
          "publicId",
          "token",
          "header",
          "part"
        ]
      },
      "CompleteTransfer": {
        "type": "object",
        "properties": {
          "operation": {
            "type": "string",
            "enum": [
              "complete"
            ]
          },
          "publicId": {
            "type": "string",
            "description": "Public transfer identifier.",
            "pattern": "^l_[a-f0-9]{32}$",
            "example": "l_0123456789abcdef0123456789abcdef"
          },
          "token": {
            "type": "string",
            "description": "Transfer capability returned by create. Separate from the workspace API key. Keep private.",
            "pattern": "^[a-f0-9]{64}$",
            "writeOnly": true
          },
          "header": {
            "type": "string",
            "description": "Unpadded base64url-encoded 24-byte libsodium secretstream header. This is not the decryption key.",
            "pattern": "^[A-Za-z0-9_-]{32}$"
          }
        },
        "required": [
          "operation",
          "publicId",
          "token",
          "header"
        ]
      },
      "TransferStatusRequest": {
        "type": "object",
        "properties": {
          "operation": {
            "type": "string",
            "enum": [
              "status"
            ]
          },
          "publicId": {
            "type": "string",
            "description": "Public transfer identifier.",
            "pattern": "^l_[a-f0-9]{32}$",
            "example": "l_0123456789abcdef0123456789abcdef"
          },
          "token": {
            "type": "string",
            "description": "Transfer capability returned by create. Separate from the workspace API key. Keep private.",
            "pattern": "^[a-f0-9]{64}$",
            "writeOnly": true
          }
        },
        "required": [
          "operation",
          "publicId",
          "token"
        ]
      },
      "TransferCheckoutRequest": {
        "type": "object",
        "properties": {
          "operation": {
            "type": "string",
            "enum": [
              "checkout"
            ]
          },
          "publicId": {
            "type": "string",
            "description": "Public transfer identifier.",
            "pattern": "^l_[a-f0-9]{32}$",
            "example": "l_0123456789abcdef0123456789abcdef"
          },
          "token": {
            "type": "string",
            "description": "Transfer capability returned by create. Separate from the workspace API key. Keep private.",
            "pattern": "^[a-f0-9]{64}$",
            "writeOnly": true
          }
        },
        "required": [
          "operation",
          "publicId",
          "token"
        ]
      },
      "StartedTransfer": {
        "type": "object",
        "properties": {
          "chunkSize": {
            "type": "integer",
            "description": "Plaintext bytes per chunk.",
            "const": 8388608
          }
        },
        "required": [
          "chunkSize"
        ]
      },
      "UploadPartUrl": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "Signed R2 URL, valid for ten minutes. PUT only encrypted bytes, without your File Link Pro Authorization header. Each part must have the expected plaintext length plus 17 bytes.",
            "format": "uri"
          }
        },
        "required": [
          "url"
        ]
      },
      "CompletedTransfer": {
        "type": "object",
        "properties": {
          "publicId": {
            "type": "string",
            "description": "Public transfer identifier.",
            "pattern": "^l_[a-f0-9]{32}$",
            "example": "l_0123456789abcdef0123456789abcdef"
          }
        },
        "required": [
          "publicId"
        ]
      },
      "TransferStatus": {
        "type": "object",
        "properties": {
          "publicId": {
            "type": "string",
            "description": "Public transfer identifier.",
            "pattern": "^l_[a-f0-9]{32}$",
            "example": "l_0123456789abcdef0123456789abcdef"
          },
          "transferId": {
            "type": "string",
            "description": "Internal transfer identifier; may be absent before upload."
          },
          "state": {
            "type": "string",
            "enum": [
              "awaiting_payment",
              "paid",
              "uploading",
              "active",
              "refunded",
              "expired"
            ]
          },
          "amount": {
            "type": "integer",
            "description": "Amount in USD cents.",
            "minimum": 0
          },
          "rate": {
            "type": "integer",
            "description": "USD cents per started binary GB.",
            "minimum": 0
          },
          "gigabytes": {
            "type": "integer",
            "description": "Plaintext size rounded up to a whole binary GB.",
            "minimum": 1,
            "maximum": 50
          },
          "included": {
            "type": "boolean"
          },
          "days": {
            "type": "integer",
            "description": "Days from initial activation. Separately purchased transfers always use 7.",
            "enum": [
              1,
              7,
              30
            ],
            "default": 7
          },
          "currency": {
            "type": "string",
            "const": "usd"
          },
          "checkoutId": {
            "type": "string",
            "description": "Stripe Checkout Session identifier, if created."
          },
          "livemode": {
            "type": "boolean"
          },
          "uploadDeadline": {
            "type": "number",
            "description": "Unix timestamp in milliseconds."
          },
          "expiresAt": {
            "type": "number",
            "description": "Unix timestamp in milliseconds."
          }
        },
        "required": [
          "publicId",
          "state",
          "amount",
          "rate",
          "gigabytes",
          "included",
          "days",
          "currency",
          "livemode",
          "uploadDeadline"
        ]
      },
      "TransferCheckout": {
        "type": "object",
        "properties": {
          "clientSecret": {
            "type": "string",
            "description": "Stripe Checkout Elements session secret. Keep private. Requires File Link Pro\u2019s matching Stripe publishable key and browser SDK to render an inline payment screen; this is not a hosted URL. Not used for included Premium uploads."
          },
          "amount": {
            "type": "integer",
            "description": "Amount in USD cents.",
            "minimum": 0
          }
        },
        "required": [
          "clientSecret",
          "amount"
        ]
      },
      "TransferRecord": {
        "type": "object",
        "properties": {
          "_id": {
            "type": "string",
            "description": "Internal transfer identifier; pass this to /api/v1/shares/{id}."
          },
          "_creationTime": {
            "type": "number",
            "description": "Unix timestamp in milliseconds."
          },
          "name": {
            "type": "string",
            "description": "Original file name.",
            "minLength": 1,
            "maxLength": 240
          },
          "size": {
            "type": "integer",
            "description": "Plaintext bytes. 1 GB = 1,073,741,824 bytes.",
            "minimum": 1,
            "maximum": 53687091200
          },
          "mime": {
            "type": "string",
            "description": "Original MIME type.",
            "maxLength": 200
          },
          "iv": {
            "type": "string",
            "description": "Public encryption initialization data, not a key."
          },
          "expiresAt": {
            "type": "number",
            "description": "Unix timestamp in milliseconds."
          },
          "state": {
            "type": "string",
            "enum": [
              "active",
              "revoked"
            ]
          },
          "downloads": {
            "type": "integer",
            "minimum": 0
          },
          "largeOrderId": {
            "type": "string",
            "description": "Internal upload order reference."
          },
          "oneOff": {
            "type": "boolean"
          }
        },
        "required": [
          "_id",
          "_creationTime",
          "name",
          "size",
          "mime",
          "iv",
          "expiresAt",
          "state",
          "downloads"
        ]
      },
      "TransferList": {
        "type": "object",
        "properties": {
          "transfers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransferRecord"
            }
          }
        },
        "required": [
          "transfers"
        ]
      },
      "Share": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Internal transfer identifier."
          },
          "publicId": {
            "type": "string",
            "description": "Public transfer identifier.",
            "pattern": "^l_[a-f0-9]{32}$",
            "example": "l_0123456789abcdef0123456789abcdef"
          },
          "name": {
            "type": "string",
            "description": "Original file name.",
            "minLength": 1,
            "maxLength": 240
          },
          "size": {
            "type": "integer",
            "description": "Plaintext bytes. 1 GB = 1,073,741,824 bytes.",
            "minimum": 1,
            "maximum": 53687091200
          },
          "mime": {
            "type": "string",
            "description": "Original MIME type.",
            "maxLength": 200
          },
          "state": {
            "type": "string",
            "enum": [
              "pending",
              "active",
              "revoked",
              "expired"
            ]
          },
          "expiresAt": {
            "type": "number",
            "description": "Unix timestamp in milliseconds."
          },
          "downloads": {
            "type": "integer",
            "minimum": 0
          },
          "hasPassword": {
            "type": "boolean"
          },
          "maxDownloads": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 1000,
            "description": "Maximum authorized download requests; null means unlimited."
          },
          "encryption": {
            "type": "string",
            "enum": [
              "secretstream-v1",
              "aes-gcm-v1"
            ],
            "description": "API-created uploads use secretstream-v1. AES describes files created by the application, not another public API version."
          },
          "downloadPath": {
            "type": "string",
            "description": "Relative recipient page path without the private key."
          }
        },
        "required": [
          "id",
          "name",
          "size",
          "mime",
          "state",
          "expiresAt",
          "downloads",
          "hasPassword",
          "maxDownloads",
          "encryption",
          "downloadPath"
        ]
      },
      "ShareSettings": {
        "type": "object",
        "properties": {
          "operation": {
            "type": "string",
            "enum": [
              "settings"
            ]
          },
          "days": {
            "type": "integer",
            "description": "Days from initial activation. Separately purchased transfers always use 7.",
            "enum": [
              1,
              7,
              30
            ],
            "default": 7
          },
          "maxDownloads": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 1000,
            "description": "Omit or send null to remove the cap."
          }
        },
        "required": [
          "operation",
          "days"
        ]
      },
      "UpdatedSettings": {
        "type": "object",
        "properties": {
          "expiresAt": {
            "type": "number",
            "description": "Unix timestamp in milliseconds."
          },
          "maxDownloads": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 1000,
            "description": "Maximum authorized download requests; null means unlimited."
          }
        },
        "required": [
          "expiresAt",
          "maxDownloads"
        ]
      },
      "SendNotifications": {
        "type": "object",
        "properties": {
          "recipients": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            },
            "minItems": 1,
            "maxItems": 10,
            "description": "Addresses are trimmed, normalized to lowercase and deduplicated."
          },
          "downloadKey": {
            "type": "string",
            "description": "Optional: explicitly include the complete private link in email. This shares the key with File Link Pro, Resend and the recipient\u2019s email provider. Omit to send a notification only and share the private link separately.",
            "pattern": "^[A-Za-z0-9_-]{43}$",
            "writeOnly": true
          }
        },
        "required": [
          "recipients"
        ]
      },
      "AcceptedNotifications": {
        "type": "object",
        "properties": {
          "notifications": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "recipient": {
                  "type": "string",
                  "format": "email"
                },
                "duplicate": {
                  "type": "boolean"
                }
              },
              "required": [
                "id",
                "recipient",
                "duplicate"
              ]
            }
          },
          "mode": {
            "type": "string",
            "enum": [
              "private_link",
              "notification_only"
            ]
          }
        },
        "required": [
          "notifications",
          "mode"
        ]
      },
      "NotificationList": {
        "type": "object",
        "properties": {
          "notifications": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "recipient": {
                  "type": "string",
                  "format": "email"
                },
                "createdAt": {
                  "type": "number",
                  "description": "Unix timestamp in milliseconds."
                },
                "includesLink": {
                  "type": "boolean"
                },
                "status": {
                  "type": "string",
                  "description": "Provider delivery status: pending, queued, sent, delivered, delayed, bounced, failed, complained, archived or another provider status. Sent does not guarantee inbox delivery."
                }
              },
              "required": [
                "id",
                "recipient",
                "createdAt",
                "includesLink",
                "status"
              ]
            }
          }
        },
        "required": [
          "notifications"
        ]
      },
      "ApiKey": {
        "type": "object",
        "properties": {
          "_id": {
            "type": "string",
            "description": "Use this identifier to revoke the key."
          },
          "_creationTime": {
            "type": "number",
            "description": "Unix timestamp in milliseconds."
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string",
            "description": "Non-secret prefix only."
          },
          "revoked": {
            "type": "boolean"
          },
          "lastUsed": {
            "type": "number",
            "description": "Unix timestamp in milliseconds."
          }
        },
        "required": [
          "_id",
          "_creationTime",
          "name",
          "prefix",
          "revoked"
        ]
      },
      "ApiKeyList": {
        "type": "object",
        "properties": {
          "keys": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiKey"
            }
          }
        },
        "required": [
          "keys"
        ]
      },
      "CreateApiKey": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Nonempty label after trimming.",
            "minLength": 1,
            "maxLength": 60
          }
        },
        "required": [
          "name"
        ]
      },
      "CreatedApiKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "token": {
            "type": "string",
            "description": "Full API key. Returned once; store securely.",
            "pattern": "^flp_[a-f0-9]{64}$"
          }
        },
        "required": [
          "id",
          "token"
        ]
      },
      "DownloadInfo": {
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string"
          },
          "fileSize": {
            "type": "integer"
          },
          "mimeType": {
            "type": "string"
          },
          "hasPassword": {
            "type": "boolean"
          },
          "maxDownloads": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 1000,
            "description": "Maximum authorized download requests; null means unlimited."
          },
          "downloadCount": {
            "type": "integer"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "accessMode": {
            "type": "string",
            "const": "PUBLIC_LINK"
          },
          "requiresIdentity": {
            "type": "boolean",
            "const": false
          },
          "encryption": {
            "type": "string",
            "const": "secretstream-v1"
          }
        },
        "required": [
          "fileName",
          "fileSize",
          "mimeType",
          "hasPassword",
          "maxDownloads",
          "downloadCount",
          "expiresAt",
          "accessMode",
          "requiresIdentity",
          "encryption"
        ]
      },
      "DownloadRequest": {
        "type": "object",
        "properties": {
          "password": {
            "type": "string",
            "description": "Required only when the transfer is password-protected.",
            "maxLength": 256,
            "writeOnly": true
          }
        },
        "required": []
      },
      "DownloadAccess": {
        "type": "object",
        "properties": {
          "blobUrl": {
            "type": "string",
            "description": "Encrypted R2 object URL, valid for 60 seconds. Fetch without your workspace API key.",
            "format": "uri"
          },
          "fileName": {
            "type": "string"
          },
          "fileSize": {
            "type": "integer"
          },
          "mimeType": {
            "type": "string"
          },
          "iv": {
            "type": "string",
            "description": "Unpadded base64url-encoded 24-byte libsodium secretstream header. This is not the decryption key.",
            "pattern": "^[A-Za-z0-9_-]{32}$"
          },
          "encryption": {
            "type": "string",
            "const": "secretstream-v1"
          },
          "chunkSize": {
            "type": "integer",
            "const": 8388608
          }
        },
        "required": [
          "blobUrl",
          "fileName",
          "fileSize",
          "mimeType",
          "iv",
          "encryption",
          "chunkSize"
        ]
      }
    }
  }
}
