{"id":49831121,"url":"https://github.com/NIyueeE/ds-free-api","last_synced_at":"2026-05-30T11:01:04.733Z","repository":{"id":346121525,"uuid":"1188066736","full_name":"NIyueeE/ds-free-api","owner":"NIyueeE","description":"DeepSeek网页端API代理，支持OpenAI与Anthropic兼容接口 | OpenAI \u0026 Anthropic compatible API proxy for DeepSeek web","archived":false,"fork":false,"pushed_at":"2026-05-26T16:27:26.000Z","size":2132,"stargazers_count":356,"open_issues_count":15,"forks_count":101,"subscribers_count":6,"default_branch":"main","last_synced_at":"2026-05-26T18:19:12.877Z","etag":null,"topics":["api","api-proxy","claude-api","deepseek-api","freeapi","openai-api","proxy-server","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NIyueeE.png","metadata":{"files":{"readme":"README.en.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-21T15:17:34.000Z","updated_at":"2026-05-26T17:55:06.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/NIyueeE/ds-free-api","commit_stats":null,"previous_names":["niyueee/deepseek-web-api","niyueee/ds-free-api"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/NIyueeE/ds-free-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NIyueeE%2Fds-free-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NIyueeE%2Fds-free-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NIyueeE%2Fds-free-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NIyueeE%2Fds-free-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NIyueeE","download_url":"https://codeload.github.com/NIyueeE/ds-free-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NIyueeE%2Fds-free-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33689564,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","api-proxy","claude-api","deepseek-api","freeapi","openai-api","proxy-server","rust"],"created_at":"2026-05-13T21:00:28.026Z","updated_at":"2026-05-30T11:01:04.725Z","avatar_url":"https://github.com/NIyueeE.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/NIyueeE/ds-free-api/main/assets/logo.svg\" width=\"81\" height=\"66\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eDS-Free-API\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/NIyueeE/ds-free-api.svg\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/github/v/release/NIyueeE/ds-free-api.svg\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/rust-1.95.0+-93450a.svg\"\u003e\n  \u003cimg src=\"https://github.com/NIyueeE/ds-free-api/actions/workflows/ci.yml/badge.svg\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/github/stars/NIyueeE/ds-free-api.svg\"\u003e\n  \u003cimg src=\"https://img.shields.io/github/forks/NIyueeE/ds-free-api.svg\"\u003e\n  \u003cimg src=\"https://img.shields.io/github/last-commit/NIyueeE/ds-free-api.svg\"\u003e\n\u003c/p\u003e\n\n[中文](README.md)\n\nA Rust API proxy that translates DeepSeek's free web chat into standard OpenAI and Anthropic-compatible API protocols (supports chat completions and messages, including streaming and tool calling).\n\n## Highlights\n\n- **Zero-cost API proxy**: Uses DeepSeek's free web interface — no official API key needed, get OpenAI/Anthropic-compatible endpoints for free\n- **Dual protocol support**: Both OpenAI Chat Completions and Anthropic Messages API, drop-in compatible with mainstream clients\n- **Tool call ready**: Full OpenAI function calling implementation with a 3-tier self-healing pipeline (text repair → JSON repair → model fallback), covering 10+ malformed formats\n- **File upload ready**: Inline data URL files in OpenAI `file`/`image_url` content parts and Anthropic `image`/`document` content blocks are automatically uploaded to DeepSeek sessions; HTTP URLs trigger search mode so the model can access link content directly\n- **Oversized prompt fallback**: When the prompt exceeds model limits, automatically falls back to chunked completion with file upload\n- **Web admin panel**: Built-in dashboard for account pool status, API key management, request logs, i18n internationalization, theme switcher, and hot-reloadable config — ready out of the box\n- **Built with Rust**: Single binary + single TOML config, cross-platform native performance (web panel compiled in at build time)\n- **Multi-account pool**: Idle-aware round-robin selection (DashMap lock-free reads), horizontal scaling for concurrency\n\n## Quick Start\n\n### Binary Usage\n\n1. Download and extract the archive for your platform from [releases](https://github.com/NIyueeE/ds-free-api/releases)\n2. Copy `config.example.toml` to `config.toml` and fill in accounts (optional — you can also configure via the admin panel after startup)\n3. Run `./ds-free-api`\n4. Visit `http://127.0.0.1:22217/admin` to set an admin password, then manage API keys and accounts from the panel\n\n```bash\n./ds-free-api\n./ds-free-api -c /path/to/config.toml\nRUST_LOG=debug ./ds-free-api\n```\n\n\u003e **Concurrency**: The free API has session-level rate limits. This project has built-in rate-limit detection + exponential backoff retry for stability.\n\u003e Recommended parallelism = accounts / 2. Supports starting without `config.toml` and adding accounts via the admin panel.\n\n### Docker Usage\n\n```bash\ndocker compose -f docker/docker-compose.yaml up -d\n```\n\nRefer to the [sample compose file](./docker/docker-compose.yaml) for reference.\n\nThe admin panel is at `http://localhost:22217/admin`. Set your admin password on first visit.\nThe `config/` and `data/` directories are bind-mounted into the container — config changes persist to the host automatically.\n\n### Free Test Accounts\n\nPlease register your own. You can refer to the method in [issue #62](https://github.com/NIyueeE/ds-free-api/issues/62).\n\n\n## API Endpoints\n\n| Method | Path | Description |\n|--------|------|-------------|\n| GET    | `/`   | Redirect to admin panel |\n| GET    | `/health` | Health check |\n| POST   | `/v1/chat/completions` | Chat completions (streaming + tool calls) |\n| GET    | `/v1/models` | List models |\n| GET    | `/v1/models/{id}` | Model details |\n| POST   | `/anthropic/v1/messages` | Anthropic Messages (streaming + tool calls) |\n| GET    | `/anthropic/v1/models` | List models (Anthropic format) |\n| GET    | `/anthropic/v1/models/{id}` | Model details (Anthropic format) |\n\nThe admin panel is at `/admin` — on first visit you'll be guided to set an admin password.\n\n## Model Mapping\n\nThe `model_types` config in `config.toml` (default `[\"default\", \"expert\", \"vision\"]`) maps to model IDs:\n\n| OpenAI Model ID    | DeepSeek Mode  |\n| ------------------ | -------------- |\n| `deepseek-default` | Fast mode      |\n| `deepseek-expert`  | Expert mode    |\n| `deepseek-vision`  | Vision mode    |\n\nOptional aliases via `model_aliases`, aligned by index with `model_types`. Empty strings are skipped:\n\n```toml\n# model_aliases = [\"\", \"deepseek-v4-pro\"]  → deepseek-v4-pro maps to expert (index 1)\nmodel_aliases = []\n```\n\nThe Anthropic compatibility layer uses the same model IDs via `/anthropic/v1/messages`.\n\n### Capability Toggles\n\n- **Deep thinking**: Enabled by default. To explicitly disable, include `\"reasoning_effort\": \"none\"` in the request body.\n- **Web search**: Enabled by default (DeepSeek injects a stronger system prompt in search mode, improving tool call adherence). To explicitly disable, include `\"web_search_options\": {\"search_context_size\": \"none\"}` in the request body.\n- **File upload**: Inline files (data URL) are auto-uploaded to DeepSeek sessions; HTTP URLs trigger search mode:\n\n  **OpenAI endpoint:**\n  ```json\n  {\"type\": \"file\", \"file\": {\"file_data\": \"data:text/plain;base64,...\", \"filename\": \"doc.txt\"}}\n  {\"type\": \"image_url\", \"image_url\": {\"url\": \"data:image/png;base64,...\"}}\n  {\"type\": \"image_url\", \"image_url\": {\"url\": \"https://example.com/img.jpg\"}}\n  ```\n\n  **Anthropic endpoint:**\n  ```json\n  {\"type\": \"image\", \"source\": {\"type\": \"base64\", \"media_type\": \"image/png\", \"data\": \"...\"}}\n  {\"type\": \"document\", \"source\": {\"type\": \"base64\", \"media_type\": \"text/plain\", \"data\": \"...\"}}\n  {\"type\": \"image\", \"source\": {\"type\": \"url\", \"url\": \"https://example.com/img.jpg\"}}\n  ```\n\n### Tool Call Tag Hallucination\n\nBuilt-in fuzzy matching handles variations (full-width `｜`\u003c=\u003e`|`, `▁`\u003c=\u003e`_`) for most formats. If the model outputs a different fallback tag, add it via the admin panel or in `config.toml` under `[ds_core]`:\n\n```toml\ntool_call.extra_starts = [\"\u003c|tool_call_begin|\u003e\", \"\u003ctool_calls\u003e\", \"\u003ctool_call\u003e\"]\ntool_call.extra_ends = [\"\u003c|tool_call_end|\u003e\", \"\u003c/tool_calls\u003e\", \"\u003c/tool_call\u003e\"]\n```\n\n## Web Admin Panel\n\nVisit `http://127.0.0.1:22217/admin` after starting the server:\n\n- **Dashboard**: Request statistics, account pool status at a glance\n- **Accounts**: View/add/remove accounts, manually re-login accounts in Error state\n- **API Keys**: Create/delete API keys, masked display\n- **Models**: Available models with details\n- **Config**: Current runtime config (sensitive fields masked)\n- **Logs**: Recent request logs and runtime logs\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/NIyueeE/ds-free-api/main/assets/web_p1.png\" alt=\"Dashboard Overview\" width=\"700\"\u003e\n  \u003cbr\u003e\n  \u003cem\u003eDashboard overview\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/NIyueeE/ds-free-api/main/assets/web_p2.png\" alt=\"Config Page\" width=\"700\"\u003e\n  \u003cbr\u003e\n  \u003cem\u003eConfig editor page\u003c/em\u003e\n\u003c/p\u003e\n\nOn first visit, you'll be guided to set an admin password (stored as bcrypt hash), then issued a JWT (24h validity). Password reset revokes old tokens.\n\n## Environment Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `RUST_LOG` | `info` | Log level (`trace` / `debug` / `info` / `warn` / `error`) |\n| `DS_DATA_DIR` | `.` (current dir) | Data directory for `logs/runtime.log` and `stats.json` |\n| `DS_CONFIG_PATH` | `./config.toml` | Config file path (lower priority than `-c` flag) |\n\n## Security\n\n- **Admin panel**: JWT authentication + bcrypt password hash + login rate limiting (5 failures → 5-minute lockout)\n- **API access**: API keys created via the admin panel (HashSet O(1) lookup)\n- **CORS**: Configurable allowed origins, defaults to `http://localhost:22217`\n- **Sensitive data**: Account IDs masked in response headers, request bodies excluded from logs, persisted files at 0600 permissions\n\n## Development\n\n### Design Philosophy\n\n**A single `config.toml` reflects all runtime state.** Admin panel changes are instantly persisted to `config.toml` and hot-reloaded into the running service.\n\n**No unnecessary runtime system dependencies.** The project prioritizes pure Rust or statically-linked dependencies (e.g., `rustls` → `wreq` with BoringSSL), ensuring a single binary with no external `.so`/`.dll` requirements — download and run.\n\n### Architecture Diagram\n\n```mermaid\nflowchart TB\n    %% ===== Theme =====\n    classDef client fill:#eff6ff,stroke:#3b82f6,stroke-width:3px,color:#1d4ed8,rx:14,ry:14\n    classDef gateway fill:#fffbeb,stroke:#f59e0b,stroke-width:3px,color:#92400e,rx:12,ry:12\n    classDef openai_adapter fill:#f8fafc,stroke:#0a9e7b,stroke-width:2px,color:#334155,rx:10,ry:10\n    classDef anthropic_compat fill:#f8fafc,stroke:#d07354,stroke-width:2px,color:#334155,rx:10,ry:10\n    classDef ds_core fill:#f8fafc,stroke:#3964fe,stroke-width:2px,color:#1e40af,rx:10,ry:10\n    classDef external fill:#fef2f2,stroke:#ef4444,stroke-width:3px,color:#991b1b,rx:6,ry:6\n\n    %% ===== Nodes =====\n    Client([\"Client\"]):::client\n\n    subgraph GW [\"HTTP Gateway Layer\"]\n        Handler([\"Router / Auth / Serialization\"]):::gateway\n    end\n\n    subgraph PL [\"Protocol Layer\"]\n        direction TB\n\n        subgraph AC [\"Anthropic Compat\"]\n            A2O[\"Request\u003cbr/\u003eAnthropic → OpenAI\"]:::anthropic_compat\n            O2A[\"Response\u003cbr/\u003eOpenAI → Anthropic\"]:::anthropic_compat\n        end\n\n        subgraph OA [\"OpenAI Adapter\"]\n            ReqPipe[\"Request Pipeline\u003cbr/\u003eValidation / Tool Extraction / Prompt Building\"]:::openai_adapter\n            RespPipe[\"Response Pipeline\u003cbr/\u003eSSE Parsing / Format Conversion / Tool Repair\"]:::openai_adapter\n        end\n    end\n\n    subgraph CL [\"Core Layer (ds_core)\"]\n        Pool[\"Account Pool Rotation\"]:::ds_core\n        PoW[\"PoW Solver\"]:::ds_core\n        Session[\"Session Orchestration\u003cbr/\u003eCreate/Destroy / History Upload\"]:::ds_core\n    end\n\n    DeepSeek[(\"DeepSeek API\")]:::external\n\n    %% ===== Connections =====\n    Client --\u003e|\"HTTP Request\"| Handler\n\n    Handler --\u003e|\"OpenAI Request\"| ReqPipe\n    Handler --\u003e|\"Anthropic Request\"| A2O\n    A2O --\u003e|\"OpenAI Request\"| ReqPipe\n\n    ReqPipe --\u003e Pool\n    Pool --\u003e PoW\n    PoW --\u003e Session\n    Session --\u003e|\"completion endpoint\"| DeepSeek\n\n    Session -.-\u003e|\"DeepSeek SSE Stream\"| RespPipe\n    RespPipe -.-\u003e|\"OpenAI Response\"| Handler\n    RespPipe -.-\u003e|\"OpenAI Response\"| O2A\n    O2A -.-\u003e|\"Anthropic Response\"| Handler\n\n    %% ===== Subgraph Styles =====\n    style GW fill:#fffbeb,stroke:#f59e0b,stroke-width:2px,stroke-dasharray: 5 5\n    style PL fill:#fafafa,stroke:#94a3b8,stroke-width:2px\n    style AC fill:#fdf0ec,stroke:#d07354,stroke-width:2px\n    style OA fill:#e6f7f3,stroke:#0a9e7b,stroke-width:2px\n    style CL fill:#eef2ff,stroke:#3964fe,stroke-width:2px,stroke-dasharray: 5 5\n```\n\n### Data Pipeline\n\n#### OpenAI (chat_completions) Pipeline:\n\n```mermaid\nflowchart TB\n    %% ===== Theme =====\n    classDef ds_core fill:#eef2ff,stroke:#3964fe,stroke-width:2.5px,color:#1e40af,rx:10,ry:10\n    classDef openai_adapter fill:#e6f7f3,stroke:#0a9e7b,stroke-width:2.5px,color:#065f46,rx:10,ry:10\n    classDef step fill:#fffbeb,stroke:#f59e0b,stroke-width:1.5px,color:#334155,rx:6,ry:6\n\n    subgraph RQ [\"Request Pipeline\"]\n        direction TB\n        Q1[\"ChatCompletionsRequest\"]:::openai_adapter\n        Q2[\"Validation + Defaults\"]:::step\n        Q3[\"Extract tools/files + inject prompts\"]:::step\n        Q4[\"Build DeepSeek native tag prompt\"]:::step\n        Q5[\"Model mapping + capability toggles\"]:::step\n        Q6[\"Retry with exp. backoff\u003cbr/\u003e1s→2s→4s→8s→16s\"]:::step\n        Q7[\"ChatRequest\"]:::ds_core\n    end\n\n    subgraph RS1 [\"Non-streaming Response\"]\n        direction TB\n        OR1[\"ds_core SSE stream\"]:::ds_core\n        OR2[\"SSE frame parse\u003cbr/\u003eContentDelta / Usage\"]:::step\n        OR3[\"State machine merge\u003cbr/\u003econtiguous text / accumulate usage\"]:::step\n        OR4[\"Chunk aggregation\u003cbr/\u003econcat content / reasoning / tool_calls\"]:::step\n        OR5[\"ChatCompletionsResponse\"]:::openai_adapter\n    end\n\n    subgraph RS2 [\"Streaming Response\"]\n        direction TB\n        OS1[\"ds_core SSE stream\"]:::ds_core\n        OS2[\"SSE frame parse + state machine\"]:::step\n        OS3[\"Chunk conversion\u003cbr/\u003eDsFrame → ChatCompletionsResponseChunk\"]:::step\n        OS4[\"Tool call XML parse\"]:::step\n        OS5[\"Malformed tool call repair\"]:::step\n        OS6[\"Stop sequence detect + obfuscation\"]:::step\n        OS7[\"ChatCompletionsResponseChunk\"]:::openai_adapter\n    end\n\n    Q1 --\u003e Q2 --\u003e Q3 --\u003e Q4 --\u003e Q5 --\u003e Q6 --\u003e Q7\n    OR1 --\u003e OR2 --\u003e OR3 --\u003e OR4 --\u003e OR5\n    OS1 --\u003e OS2 --\u003e OS3 --\u003e OS4 --\u003e OS5 --\u003e OS6 --\u003e OS7\n\n    style RQ fill:#f8fafc,stroke:#0a9e7b,stroke-width:2px\n    style RS1 fill:#f8fafc,stroke:#0a9e7b,stroke-width:2px\n    style RS2 fill:#f8fafc,stroke:#0a9e7b,stroke-width:2px\n```\n\n#### Anthropic (messages) Pipeline:\n\n```mermaid\nflowchart TB\n    %% ===== Theme =====\n    classDef oai fill:#e6f7f3,stroke:#0a9e7b,stroke-width:2.5px,color:#065f46,rx:10,ry:10\n    classDef anth fill:#fdf0ec,stroke:#d07354,stroke-width:2.5px,color:#7c3a2a,rx:10,ry:10\n    classDef step fill:#fffbeb,stroke:#f59e0b,stroke-width:1.5px,color:#334155,rx:6,ry:6\n\n    subgraph RQ [\"Request Pipeline\"]\n        direction TB\n        Q1[\"MessagesRequest\"]:::anth\n        Q2[\"Message expansion\u003cbr/\u003eSystem prepend / text merge / image+document mapping\"]:::step\n        Q3[\"Tool mapping\u003cbr/\u003eToolUnion → OpenAI Tool\"]:::step\n        Q4[\"Capability toggle mapping\u003cbr/\u003ethinking → reasoning_effort\"]:::step\n        Q5[\"ChatCompletionsRequest\"]:::oai\n    end\n\n    subgraph RS3 [\"Non-streaming Response\"]\n        direction TB\n        AR1[\"ChatCompletionsResponse\"]:::oai\n        AR2[\"Content decomposition\u003cbr/\u003ereasoning → Thinking\u003cbr/\u003econtent → Text\u003cbr/\u003etool_calls → ToolUse\"]:::step\n        AR3[\"ID mapping\u003cbr/\u003echatcmpl → msg\u003cbr/\u003ecall → toolu\"]:::step\n        AR4[\"MessagesResponse\"]:::anth\n    end\n\n    subgraph RS4 [\"Streaming Response\"]\n        direction TB\n        AS1[\"ChatCompletionsResponseChunk stream\"]:::oai\n        AS2[\"Chunk state machine\u003cbr/\u003eblock type switch / index progression\"]:::step\n        AS3[\"Event mapping\u003cbr/\u003econtent → text_delta\u003cbr/\u003ereasoning → thinking_delta\u003cbr/\u003etool_calls → input_json_delta\"]:::step\n        AS4[\"MessagesResponseChunk\"]:::anth\n    end\n\n    Q1 --\u003e Q2 --\u003e Q3 --\u003e Q4 --\u003e Q5\n    AR1 --\u003e AR2 --\u003e AR3 --\u003e AR4\n    AS1 --\u003e AS2 --\u003e AS3 --\u003e AS4\n\n    style RQ fill:#f8fafc,stroke:#d07354,stroke-width:2px\n    style RS3 fill:#f8fafc,stroke:#d07354,stroke-width:2px\n    style RS4 fill:#f8fafc,stroke:#d07354,stroke-width:2px\n```\n\nFor detailed development guide (building, testing, Docker deployment, e2e testing, etc.), see [docs/development.md](./docs/development.md).\n\n## License\n\n[GNU General Public License v3.0](LICENSE)\n\n[DeepSeek's official API](https://platform.deepseek.com/top_up) is very affordable — please support the official service.\n\nThis project was born from the desire to try the latest models in DeepSeek's web interface during grayscale testing.\n\n**Commercial use is strictly prohibited** to avoid putting pressure on official servers. Use at your own risk.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNIyueeE%2Fds-free-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNIyueeE%2Fds-free-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNIyueeE%2Fds-free-api/lists"}