Dropstone CLI

HTTP API

Public HTTP API for programmatic access. OpenAI-compatible chat completions, pay-per-use credits, one key for Fast / Pro / Heavy.

The Dropstone HTTP API gives you programmatic access to the same three models the CLI uses — Dropstone Fast, Pro, and Heavy — over an OpenAI-compatible interface. One key, one bill, three model families.

Use the API when you want to call Dropstone from your own code: CI pipelines, internal tools, automation, or third-party apps. For interactive coding, use the CLI instead.

Status

The public API is in preview. The endpoint shape is stable but pricing and rate limits may change before GA. Pin the surface you depend on.


Base URL

https://api.dropstone.io/api/v1

All endpoints are mounted under /api/v1. The path is versioned so future breaking changes will land under /api/v2 without disrupting your code.


Authentication

Every request must include an API key in the Authorization header:

Authorization: Bearer dsk_live_<your-key>

Generate a key

  1. Sign in to dropstone.io/dashboard
  2. Open Settings → API
  3. Click Create key, give it a name (e.g. Production CI)
  4. Copy the full key — you will only see it once

Keys look like dsk_live_<43 chars>. Store them in a secrets manager or in the DROPSTONE_API_KEY environment variable.

Revoking a key

Revoke from the same Settings → API page. Revocation is immediate; in-flight requests with the key continue, new requests get 401.

Security

Treat your API key like a password. Never commit it to git, never paste it in chat or screenshots, never embed it in a frontend bundle. If a key leaks, revoke it immediately and create a new one.


Credits & billing

The API is pay-per-use against a credit balance. There is no free tier and no subscription on the API surface.

  • Buy credits at dropstone.io/dashboard/billing. Stripe handles checkout.
  • Each request deducts its cost from your creditBalance.
  • When creditBalance drops to $0, the API returns 402 Insufficient credits until you top up.
  • Subscription credits (Pro/Teams monthly allowance) and free-request quotas do not apply to API key requests.

Pricing

Pricing is real inference cost passed through with a 30% markup (1.3x). The full per-request cost is returned in the response usage.cost field, so you can verify every charge.

TierApprox $/M inputApprox $/M output
dropstone-fast$0.35$1.43
dropstone-pro$0.72$2.86
dropstone-heavy$0.78$3.25

Cached prompt tokens are billed at the provider's cached rate (typically ~5–10% of the normal input rate), so multi-turn conversations get progressively cheaper.


Models

GET /api/v1/models

List the three available tiers.

curl https://api.dropstone.io/api/v1/models \
  -H "Authorization: Bearer $DROPSTONE_API_KEY"

Response:

{
  "object": "list",
  "data": [
    { "id": "dropstone-fast",  "object": "model", "display_name": "Dropstone Fast",  "owned_by": "dropstone" },
    { "id": "dropstone-pro",   "object": "model", "display_name": "Dropstone Pro",   "owned_by": "dropstone" },
    { "id": "dropstone-heavy", "object": "model", "display_name": "Dropstone Heavy", "owned_by": "dropstone" }
  ]
}

Chat completions

POST /api/v1/chat/completions

OpenAI-compatible chat completions. If you have used any OpenAI-compatible API, this looks identical.

Request body

| Field | Type | Required | Description | |---|---|---| | model | string | yes | One of dropstone-fast, dropstone-pro, dropstone-heavy | | messages | array | yes | List of message objects with role and content | | stream | boolean | no | When true, returns Server-Sent Events. Default false | | temperature | number | no | Sampling temperature, 0..2. Default model-specific | | max_tokens | number | no | Cap on output tokens | | tools | array | no | Function-calling tool schemas, OpenAI format | | tool_choice | string \| object | no | "auto", "none", or a specific tool |

Example: simple chat

curl https://api.dropstone.io/api/v1/chat/completions \
  -H "Authorization: Bearer $DROPSTONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "dropstone-fast",
    "messages": [
      {"role": "user", "content": "Write a haiku about debugging."}
    ]
  }'

Response

{
  "id": "gen-1779530142-EfBhlhO1U2frV6tvMgKV",
  "object": "chat.completion",
  "created": 1779530142,
  "model": "dropstone-fast",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Stack trace at midnight..." },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 11,
    "completion_tokens": 23,
    "total_tokens": 34,
    "cost": 0.0000098
  }
}

The usage.cost field is the billed amount in USD — what was deducted from your credit balance for this request (real provider cost × 1.3 markup).


Streaming

Set "stream": true to get a Server-Sent Events stream of token chunks. The stream ends with a data: [DONE] line and a final chunk containing the full usage block.

curl https://api.dropstone.io/api/v1/chat/completions \
  -H "Authorization: Bearer $DROPSTONE_API_KEY" \
  -H "Content-Type: application/json" \
  -N \
  -d '{
    "model": "dropstone-fast",
    "stream": true,
    "messages": [{"role": "user", "content": "Count to 5."}]
  }'

OpenAI SDK compatibility

Because the surface is OpenAI-compatible, you can use the official OpenAI SDK by overriding base_url:

from openai import OpenAI

client = OpenAI(
    base_url="https://api.dropstone.io/api/v1",
    api_key=os.environ["DROPSTONE_API_KEY"],
)

resp = client.chat.completions.create(
    model="dropstone-fast",
    messages=[{"role": "user", "content": "Hello"}],
)
print(resp.choices[0].message.content)

Error codes

CodeMeaningAction
400Invalid request body (bad model, missing messages, etc.)Check the response error.message
401Missing, malformed, or revoked API keyGenerate a new key in the dashboard
402Insufficient credits. Balance is $0 or negativeTop up at /dashboard/billing
403Account suspended or bannedContact support
429Rate limit (future — not enforced today)Back off and retry
500Server errorRetry with exponential backoff
502Upstream provider errorRetry with exponential backoff

402 response shape

{
  "error": "Insufficient credits",
  "balance": 0,
  "message": "Your credit balance is empty. Top up at https://dropstone.io/dashboard/billing to continue.",
  "topUpUrl": "https://dropstone.io/dashboard/billing"
}

Rate limits

There are no hard rate limits enforced on the API today. Per-key usage tiers and daily spend caps are planned — when they ship, your existing keys will be auto-tiered based on lifetime spend, similar to OpenAI's tier system.

For now, set per-key budgets yourself by tracking the usage.cost field in your application.


  • Use environment variables, never inline keys: DROPSTONE_API_KEY=dsk_live_....
  • One key per service, not one key shared everywhere. Easier to revoke when a service is compromised.
  • Watch usage.cost in responses to track spend in real time.
  • Handle 402 gracefully — your app should detect it and surface a top-up CTA rather than retrying.
  • Cache responses for repeated identical requests on your side — we cache at the model level, but you save the full markup by short-circuiting before reaching us.

Differences from the CLI and SDK

| Surface | Auth | Pricing model | Models | Use case | |---|---|---|---| | HTTP API (this page) | API key | Pay-per-use from credit balance | Fast / Pro / Heavy | CI, automation, integrations | | CLI (docs) | Interactive sign-in | Subscription + credit balance | Same three + free open-source models | Day-to-day coding in a terminal | | JS SDK (docs) | Spawns local CLI, inherits its auth | Same as CLI | Same as CLI | Embedding the agent in a Node app |

If you want headless programmatic access in CI or a server, the HTTP API is the right surface. The SDK is for embedding the interactive agent in a Node process where a human is still in the loop.


Coming soon

These are on the roadmap and will land under the same /api/v1 namespace:

  • POST /api/v1/agent/run — agent loop endpoint. Send a task, get a finished diff. Server-side multi-turn loop with built-in tools (file editing, web search, code execution). Flat per-task pricing.
  • POST /api/v1/memory/store + GET /api/v1/memory/query — stateful memory via Qdrant. Agent context that persists across calls.
  • MCP tool injection — include your own MCP server URLs in agent requests, agent calls them as native tools.
  • Per-key spend caps — set a daily $ limit per key from the dashboard. CI safety net.

Star the GitHub repo or watch the changelog to know when they ship.

Ctrl+I