{
  "openapi": "3.1.1",
  "info": {
    "title": "rafb.me API",
    "description": "Pastes and short links. Send `Authorization: Bearer rafb_…` (create keys at /account/api). Human-readable docs: /docs/api",
    "version": "1"
  },
  "servers": [
    {
      "url": "https://rafb.me/"
    }
  ],
  "paths": {
    "/api/v1": {
      "get": {
        "tags": [
          "RafbMe.Web"
        ],
        "summary": "API info; also a quick way to check a key",
        "description": "Works without a key. With a valid key, `authenticated` is true and `user` names the account.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiRoot"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/languages": {
      "get": {
        "tags": [
          "RafbMe.Web"
        ],
        "summary": "Syntax highlighting languages accepted by pastes",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LanguageInfo"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/pastes": {
      "post": {
        "tags": [
          "Pastes"
        ],
        "summary": "Create a paste",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePasteRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PasteResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Pastes"
        ],
        "summary": "List your pastes",
        "description": "Newest first. Expired pastes are excluded; content is omitted.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PasteResponse"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/pastes/{id}": {
      "get": {
        "tags": [
          "Pastes"
        ],
        "summary": "Get one of your pastes, with its content",
        "description": "Doesn't count a view or burn a burn-after-reading paste. Anyone's paste can be read publicly at its rawUrl.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PasteResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Pastes"
        ],
        "summary": "Delete one of your pastes",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/links": {
      "post": {
        "tags": [
          "Short links"
        ],
        "summary": "Shorten a URL",
        "description": "Rejects non-http(s) URLs, private/local addresses, URLs with credentials, links back to rafb.me, and (when enabled) URLs Google Safe Browsing flags.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLinkRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LinkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Short links"
        ],
        "summary": "List your short links",
        "description": "Newest first, with click counts. Expired links are excluded.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LinkResponse"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/links/{code}": {
      "get": {
        "tags": [
          "Short links"
        ],
        "summary": "Get one of your short links, with its click count",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LinkResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Short links"
        ],
        "summary": "Delete one of your short links",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ApiError": {
        "required": [
          "error",
          "code"
        ],
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "field": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "ApiRoot": {
        "required": [
          "name",
          "version",
          "documentation",
          "openApi",
          "authenticated",
          "user"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "documentation": {
            "type": "string"
          },
          "openApi": {
            "type": "string"
          },
          "authenticated": {
            "type": "boolean"
          },
          "user": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "CreateLinkRequest": {
        "required": [
          "url"
        ],
        "type": "object",
        "properties": {
          "url": {
            "type": [
              "null",
              "string"
            ],
            "description": "The destination: an http(s) URL. A bare domain gets https:// added."
          },
          "alias": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional custom code: 3–32 letters, digits, - or _. Case-insensitive."
          },
          "expiry": {
            "type": [
              "null",
              "string"
            ],
            "description": "10m, 1h, 1d, 1w, 1mo or never (default)."
          }
        }
      },
      "CreatePasteRequest": {
        "required": [
          "content"
        ],
        "type": "object",
        "properties": {
          "content": {
            "type": [
              "null",
              "string"
            ],
            "description": "The text to share. Required; up to the server's size limit (512 KiB by default)."
          },
          "title": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional title, up to 200 characters."
          },
          "language": {
            "type": [
              "null",
              "string"
            ],
            "description": "Syntax highlighting language id, e.g. \"csharp\", \"plsql\", \"json\". Omit for plain text."
          },
          "expiry": {
            "type": [
              "null",
              "string"
            ],
            "description": "10m, 1h, 1d, 1w (default), 1mo or never."
          },
          "burnAfterReading": {
            "type": "boolean",
            "description": "Delete the paste after it's viewed once.",
            "default": false
          }
        }
      },
      "LanguageInfo": {
        "required": [
          "id",
          "name"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "LinkResponse": {
        "required": [
          "code",
          "shortUrl",
          "infoUrl",
          "targetUrl",
          "createdUtc",
          "expiresUtc",
          "clicks",
          "lastClickUtc"
        ],
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "shortUrl": {
            "type": "string"
          },
          "infoUrl": {
            "type": "string"
          },
          "targetUrl": {
            "type": "string"
          },
          "createdUtc": {
            "type": "string",
            "format": "date-time"
          },
          "expiresUtc": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "clicks": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "lastClickUtc": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "PasteResponse": {
        "required": [
          "id",
          "url",
          "rawUrl",
          "title",
          "language",
          "createdUtc",
          "expiresUtc",
          "burnAfterReading",
          "views",
          "length"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "rawUrl": {
            "type": "string"
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "language": {
            "type": [
              "null",
              "string"
            ]
          },
          "createdUtc": {
            "type": "string",
            "format": "date-time"
          },
          "expiresUtc": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "burnAfterReading": {
            "type": "boolean"
          },
          "views": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "length": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "content": {
            "type": [
              "null",
              "string"
            ],
            "description": "Included when fetching a single paste; omitted in lists."
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "RafbMe.Web"
    },
    {
      "name": "Pastes"
    },
    {
      "name": "Short links"
    }
  ]
}