{
 "openapi": "3.1.0",
 "info": {
  "title": "Open Source Everything API",
  "version": "1.0.0",
  "summary": "Open-source replacements for closed-source apps: read-only lookups.",
  "description": "Open-source replacements for closed apps, grouped by the job they do, and the jobs nothing open does yet. Read-only, no sign-in. Data is CC BY-SA 4.0: cite the `page` URLs. Listings were drafted with AI assistance and are managed by r/TrueOpenSource moderators. For non-technical users prefer fit \"full\" and setup \"easy\". The same data is also published as static files (see /llms.txt) and as an MCP server at https://api.opensourceeverything.org/mcp.",
  "license": {
   "name": "CC BY-SA 4.0",
   "url": "https://creativecommons.org/licenses/by-sa/4.0/"
  },
  "contact": {
   "name": "r/TrueOpenSource",
   "url": "https://www.reddit.com/r/TrueOpenSource/"
  }
 },
 "externalDocs": {
  "description": "Guide for AI agents",
  "url": "https://opensourceeverything.org/ai/"
 },
 "servers": [
  {
   "url": "https://api.opensourceeverything.org"
  }
 ],
 "paths": {
  "/v1/search": {
   "get": {
    "operationId": "search",
    "summary": "Search by app name, job, or plain-words need (same ranking as the website search)",
    "parameters": [
     {
      "name": "q",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "minLength": 2,
       "maxLength": 200
      },
      "description": "e.g. \"alternative to Notion\" or \"private photo backup\""
     },
     {
      "name": "device",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "windows",
        "mac",
        "linux",
        "android",
        "ios",
        "web"
       ]
      },
      "description": "The user's device. Projects that run there are listed first; others are marked, not hidden."
     },
     {
      "name": "setup",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "easy",
        "advanced"
       ]
      },
      "description": "Only projects with this setup rating. Use easy for non-technical users."
     },
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 30
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Closed apps, groups and projects, best first, each with a page link.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/Slow"
     }
    }
   }
  },
  "/v1/apps/{slug}": {
   "get": {
    "operationId": "alternativesTo",
    "summary": "Open alternatives to one closed app (the main question)",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The app's name or address slug, e.g. \"photoshop\" or \"Google Docs\"."
     },
     {
      "name": "device",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "windows",
        "mac",
        "linux",
        "android",
        "ios",
        "web"
       ]
      },
      "description": "The user's device. Projects that run there are listed first; others are marked, not hidden."
     },
     {
      "name": "setup",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "easy",
        "advanced"
       ]
      },
      "description": "Only projects with this setup rating. Use easy for non-technical users."
     },
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 30
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Alternatives across all the app's groups, best first, with fit, setup and the reason for the order.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/Slow"
     }
    }
   }
  },
  "/v1/groups/{id}": {
   "get": {
    "operationId": "getGroup",
    "summary": "One job and every alternative, ranked",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Group id, e.g. \"photo-editing\"."
     },
     {
      "name": "device",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "windows",
        "mac",
        "linux",
        "android",
        "ios",
        "web"
       ]
      },
      "description": "The user's device. Projects that run there are listed first; others are marked, not hidden."
     },
     {
      "name": "setup",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "easy",
        "advanced"
       ]
      },
      "description": "Only projects with this setup rating. Use easy for non-technical users."
     }
    ],
    "responses": {
     "200": {
      "description": "Group with coverage and ranked alternatives.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/Slow"
     }
    }
   }
  },
  "/v1/projects/{id}": {
   "get": {
    "operationId": "getProject",
    "summary": "Every fact about one project",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Project id, e.g. \"immich\"."
     }
    ],
    "responses": {
     "200": {
      "description": "Project facts, family and the groups it is listed in.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/Slow"
     }
    }
   }
  },
  "/v1/projects/{id}/contribute": {
   "get": {
    "operationId": "howToContribute",
    "summary": "Where to help a project",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Project id."
     }
    ],
    "responses": {
     "200": {
      "description": "Contributing guide, good-first-issue and help-wanted links.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/Slow"
     }
    }
   }
  },
  "/v1/gaps": {
   "get": {
    "operationId": "listGaps",
    "summary": "Jobs open source does not do (fully) yet",
    "parameters": [
     {
      "name": "category",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "coverage",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "none",
        "partial",
        "one-full"
       ]
      }
     },
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 150
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Gaps, nothing-open-yet first.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/Slow"
     }
    }
   }
  },
  "/v1/compare": {
   "get": {
    "operationId": "compare",
    "summary": "Side-by-side facts for 2 to 6 projects",
    "parameters": [
     {
      "name": "ids",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Comma-separated project ids, e.g. \"gimp,krita\"."
     }
    ],
    "responses": {
     "200": {
      "description": "Facts side by side, how they are related, shared jobs.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/Slow"
     }
    }
   }
  }
 },
 "components": {
  "responses": {
   "NotFound": {
    "description": "Nothing matches; the error message suggests close names.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "Slow": {
    "description": "Too many requests from this address; wait a little.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   }
  },
  "schemas": {
   "Error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "string"
     }
    },
    "required": [
     "error"
    ]
   }
  }
 }
}