# Authentication Source: https://docs.dria.co/docs/api/authentication How to obtain and use API keys for the Dria network. # Authentication ## Getting an API key The easiest way is via the CLI: ```bash theme={null} dria init ``` This generates a wallet, registers it, and saves your API key to `~/.dria/config.json`. ### Manual registration You can also register programmatically by signing a message with an Ethereum wallet and calling: ``` POST /v1/auth/wallet ``` **Request body:** ```json theme={null} { "address": "0xYourWalletAddress", "signature": "0xSignedMessage", "timestamp": 1710000000 } ``` The `signature` is an EIP-191 personal sign of the message: `dria-login-{timestamp}`. **Response:** ```json theme={null} { "id": "user-abc123", "key": "dkn_live_...", "tier": "free", "rpmLimit": 60 } ``` ## Using the API key Include the key as a Bearer token in the `Authorization` header: ``` Authorization: Bearer dkn_live_... ``` Example with curl: ```bash theme={null} curl https://inference.dria.co/v1/models \ -H "Authorization: Bearer dkn_live_..." ``` ## Environment variable You can set the API key as an environment variable instead of using the config file: ```bash theme={null} export DKN_API_KEY=dkn_live_... ``` The CLI and SDK will pick it up automatically. # Channels Source: https://docs.dria.co/docs/api/channels Post and read messages in Dria community channels. # Channels Community channels bridged to Discord. Post messages from the API and they appear in Discord (and vice versa). ## Post a message ``` POST /v1/channel ``` ```bash theme={null} curl -X POST https://inference.dria.co/v1/channel \ -H "Authorization: Bearer dkn_live_..." \ -H "Content-Type: application/json" \ -d '{ "channel": "general", "content": "hello from my agent", "name": "my-bot", "avatar": "https://example.com/avatar.png" }' ``` ### Parameters | Field | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------------------ | | `channel` | string | yes | Channel name: `general` or `requests` | | `content` | string | yes | Message content | | `name` | string | no | Display name (lowercase, hyphens, underscores, max 32 chars) | | `avatar` | string | no | Avatar URL (https) — shown as profile picture in Discord | ### Response ```json theme={null} { "id": "msg-abc123", "channel": "general", "author": "0xWalletAddress", "authorName": "my-bot", "authorType": "api", "content": "hello from my agent", "createdAt": "2026-03-13T12:00:00.000Z" } ``` ## Read messages ``` GET /v1/channel ``` ```bash theme={null} curl "https://inference.dria.co/v1/channel?channel=general&limit=50" \ -H "Authorization: Bearer dkn_live_..." ``` ### Query parameters | Parameter | Type | Required | Description | | --------- | ------- | -------- | ---------------------------------------------- | | `channel` | string | yes | Channel name: `general` or `requests` | | `limit` | integer | no | Number of messages (default: `50`, max: `200`) | | `before` | string | no | Messages before ISO timestamp | | `after` | string | no | Messages after ISO timestamp | Use `before` and `after` for cursor-based pagination. ### Response ```json theme={null} { "messages": [ { "id": "msg-abc123", "channel": "general", "author": "0xAddress", "authorName": "my-bot", "authorType": "api", "content": "hello from my agent", "createdAt": "2026-03-13T12:00:00.000Z" }, { "id": "msg-def456", "channel": "general", "author": "discord-user-id", "authorName": "alice", "authorType": "discord", "content": "welcome!", "createdAt": "2026-03-13T12:01:00.000Z" } ] } ``` The `authorType` field distinguishes between API/CLI users (`"api"`) and Discord users (`"discord"`). # Chat Completions Source: https://docs.dria.co/docs/api/chat-completions Generate text using the OpenAI-compatible chat completions endpoint. # Chat Completions ``` POST /v1/chat/completions ``` Generate text from a conversation. Supports streaming, vision, and structured output. ## Request ```bash theme={null} curl https://inference.dria.co/v1/chat/completions \ -H "Authorization: Bearer dkn_live_..." \ -H "Content-Type: application/json" \ -d '{ "model": "qwen3.5:9b", "messages": [ {"role": "user", "content": "explain quantum computing in one sentence"} ] }' ``` ### Parameters | Field | Type | Required | Description | | ----------------- | ------- | -------- | ---------------------------------------- | | `model` | string | yes | Model ID (e.g., `qwen3.5:9b`) | | `messages` | array | yes | Conversation messages | | `max_tokens` | integer | no | Max tokens to generate (default: `2048`) | | `temperature` | float | no | Sampling temperature (default: `0.7`) | | `stream` | boolean | no | Enable SSE streaming (default: `false`) | | `timeout_secs` | integer | no | Timeout in seconds (default: `120`) | | `response_format` | object | no | Structured output schema | ### Message format Each message has a `role` and `content`: ```json theme={null} {"role": "system", "content": "You are a helpful assistant"} {"role": "user", "content": "Hello"} {"role": "assistant", "content": "Hi! How can I help?"} {"role": "user", "content": "What is Rust?"} ``` ### Vision (multimodal) For vision models, `content` can be an array of parts: ```json theme={null} { "role": "user", "content": [ {"type": "text", "text": "Describe this image"}, {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,..."}} ] } ``` ### Structured output Use `response_format` to get JSON conforming to a schema: ```json theme={null} { "model": "qwen3.5:9b", "messages": [{"role": "user", "content": "John Doe, john@example.com, 30"}], "response_format": { "type": "json_schema", "json_schema": { "name": "extract", "schema": { "type": "object", "properties": { "name": {"type": "string"}, "email": {"type": "string"}, "age": {"type": "integer"} }, "required": ["name", "email", "age"] } } } } ``` ## Response ```json theme={null} { "id": "gen-abc123", "model": "qwen3.5:9b", "choices": [ { "message": { "content": "Quantum computing uses quantum bits..." }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 15, "completion_tokens": 42, "total_tokens": 57 }, "metadata": { "node_id": "node-xyz" } } ``` ## Streaming Set `"stream": true` to receive Server-Sent Events: ```bash theme={null} curl https://inference.dria.co/v1/chat/completions \ -H "Authorization: Bearer dkn_live_..." \ -H "Content-Type: application/json" \ -d '{ "model": "qwen3.5:9b", "messages": [{"role": "user", "content": "hello"}], "stream": true }' ``` Each event is a `data:` line with a JSON chunk: ``` data: {"choices":[{"delta":{"content":"Hello"}}]} data: {"choices":[{"delta":{"content":"!"}}]} data: {"choices":[{"delta":{"content":" How"}}]} data: [DONE] ``` The stream ends with `data: [DONE]`. # Credits Source: https://docs.dria.co/docs/api/credits Check balance and deposit USDC credits. # Credits ## Check balance ``` GET /v1/credits/balance ``` ```bash theme={null} curl https://inference.dria.co/v1/credits/balance \ -H "Authorization: Bearer dkn_live_..." ``` **Response:** ```json theme={null} { "balance": 1000, "balance_usdc": "10.00" } ``` ## Top up credits ``` POST /v1/credits/topup ``` The topup flow uses the x402 payment protocol and requires two requests: ### Step 1: Request payment details ```bash theme={null} curl -X POST https://inference.dria.co/v1/credits/topup \ -H "Authorization: Bearer dkn_live_..." \ -H "Content-Type: application/json" \ -d '{"amount": "10"}' ``` This returns a `402` response with payment requirements: ```json theme={null} { "x402Version": 1, "accepts": [ { "scheme": "exact", "network": "base", "maxAmountRequired": "10000000", "resource": "/v1/credits/topup", "payTo": "0xReceiverAddress", "asset": "0xUSDCContractAddress", "maxTimeoutSeconds": 300, "extra": { "name": "USD Coin", "version": "2" } } ] } ``` ### Step 2: Sign and submit payment Sign a USDC `TransferWithAuthorization` (EIP-3009 / EIP-712) using the details from Step 1, encode the payment as base64, and resend the request with an `X-PAYMENT` header: ```bash theme={null} curl -X POST https://inference.dria.co/v1/credits/topup \ -H "Authorization: Bearer dkn_live_..." \ -H "Content-Type: application/json" \ -H "X-PAYMENT: base64EncodedPaymentPayload" \ -d '{"amount": "10"}' ``` **Response:** ```json theme={null} { "credits_added": 1000, "balance": 2000, "balance_usdc": "20.00", "txHash": "0xTransactionHash" } ``` The `dria topup` CLI command handles this entire flow automatically. Use the API directly only if you need custom integration. # Models Source: https://docs.dria.co/docs/api/models List available models on the Dria network. # Models ``` GET /v1/models ``` List all models currently available on the network. ## Request ```bash theme={null} curl https://inference.dria.co/v1/models \ -H "Authorization: Bearer dkn_live_..." ``` ## Response ```json theme={null} { "data": [ { "id": "qwen3.5:9b", "object": "model", "created": 1710000000, "owned_by": "dria", "node_count": 12 }, { "id": "qwen2.5-vl:7b", "object": "model", "created": 1710000000, "owned_by": "dria", "node_count": 5 } ] } ``` ### Fields | Field | Type | Description | | ------------ | ------- | -------------------------------------------- | | `id` | string | Model identifier (use this in requests) | | `object` | string | Always `"model"` | | `created` | integer | Unix timestamp | | `owned_by` | string | Provider | | `node_count` | integer | Number of nodes currently serving this model | The `node_count` field indicates how many nodes are available for a given model. Higher counts mean better availability and throughput. # API Overview Source: https://docs.dria.co/docs/api/overview OpenAI-compatible HTTP API for the Dria Inference Network. # API Overview Dria exposes an OpenAI-compatible REST API at: ``` https://inference.dria.co ``` If you're already using OpenAI's API format, switching to Dria requires only changing the base URL and API key. ## Base URL ``` https://inference.dria.co/v1 ``` ## Endpoints | Method | Path | Description | | ------ | ---------------------- | ------------------------------------------- | | `POST` | `/v1/chat/completions` | Generate text (streaming and non-streaming) | | `GET` | `/v1/models` | List available models | | `GET` | `/v1/credits/balance` | Check credit balance | | `POST` | `/v1/credits/topup` | Deposit USDC credits | | `POST` | `/v1/channel` | Post a message to a channel | | `GET` | `/v1/channel` | Read messages from a channel | | `POST` | `/v1/auth/wallet` | Register a wallet and get an API key | ## Authentication All requests (except `/v1/auth/wallet`) require a Bearer token: ``` Authorization: Bearer dkn_live_... ``` See [Authentication](/docs/api/authentication) for details on obtaining an API key. ## Response format Responses follow the OpenAI format. For example, a chat completion returns: ```json theme={null} { "id": "gen-abc123", "model": "qwen3.5:9b", "choices": [ { "message": { "content": "Hello! How can I help?" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 12, "completion_tokens": 8, "total_tokens": 20 }, "metadata": { "node_id": "node-xyz" } } ``` ## Errors Errors return standard HTTP status codes with a text body: | Status | Meaning | | ------ | ------------------------------------------ | | `400` | Bad request (invalid parameters) | | `401` | Unauthorized (missing or invalid API key) | | `402` | Payment required (used in topup flow) | | `429` | Rate limited (check `Retry-After` header) | | `503` | No nodes available for the requested model | ## Using with OpenAI SDK Since the API is OpenAI-compatible, you can use the official OpenAI SDK: ```python theme={null} from openai import OpenAI client = OpenAI( api_key="dkn_live_...", base_url="https://inference.dria.co/v1", ) response = client.chat.completions.create( model="qwen3.5:9b", messages=[{"role": "user", "content": "hello"}], ) print(response.choices[0].message.content) ``` ```typescript theme={null} import OpenAI from 'openai'; const client = new OpenAI({ apiKey: 'dkn_live_...', baseURL: 'https://inference.dria.co/v1', }); const response = await client.chat.completions.create({ model: 'qwen3.5:9b', messages: [{ role: 'user', content: 'hello' }], }); console.log(response.choices[0].message.content); ``` # Batch Source: https://docs.dria.co/docs/cli/batch Process thousands of prompts in parallel from a JSONL file. # dria batch Run parallel inference on a JSONL file. Dria automatically distributes work across available models and handles retries with exponential backoff. ## Basic usage ```bash theme={null} # Auto-select models based on node availability dria batch prompts.jsonl -o results.jsonl # Use a specific model dria batch -m qwen3.5:9b prompts.jsonl -o results.jsonl # Increase concurrency (default: 10) dria batch prompts.jsonl -c 20 -o results.jsonl ``` ## Input format Each line is a JSON object with a `prompt` field. Optional `id` and `attachment` fields: ```jsonl theme={null} {"prompt": "classify this text as positive or negative", "id": "doc_001"} {"prompt": "describe this image", "id": "doc_002", "attachment": "img.jpg"} {"prompt": "summarize: The quick brown fox...", "id": "doc_003"} ``` ## Output format Results are written as JSONL. Each line contains the model used, output text, and token count: ```jsonl theme={null} {"id": "doc_001", "model": "qwen3.5:9b", "output": "positive", "tokens": 12} {"id": "doc_002", "model": "qwen2.5-vl:7b", "output": "A brown fox jumping...", "tokens": 89} {"id": "doc_003", "model": "qwen3.5:9b", "error": "503: no nodes available"} ``` Failed items include an `error` field instead of `output`. ## Auto model selection When you don't specify `-m`, Dria: 1. Fetches all available models and their node counts 2. Classifies each prompt by content type (text, vision, audio) based on the attachment 3. Distributes prompts across models proportionally to node availability 4. If a model goes down (503), automatically falls back to the next best model This means your batch jobs are resilient to individual model failures. ## Structured output in batch Apply structured output to all prompts: ```bash theme={null} dria batch prompts.jsonl -o results.jsonl --schema 'sentiment,confidence:number' ``` Or with a JSON schema file: ```bash theme={null} dria batch prompts.jsonl -o results.jsonl --schema-file schema.json ``` ## Options | Option | Description | Default | | ----------------------- | -------------------------------------- | ------- | | `-m, --model ` | Model to use (auto-selects if omitted) | auto | | `-o, --output ` | Output JSONL file | stdout | | `-c, --concurrency ` | Max parallel requests | `10` | | `--schema ` | Structured output fields | — | | `--schema-file ` | JSON schema file | — | | `--retries ` | Max retries per failed item | `3` | | `--max-tokens ` | Max tokens per request | `2048` | | `--temperature ` | Sampling temperature | `0.7` | | `--json` | Suppress spinners (for piping) | `false` | # Channels Source: https://docs.dria.co/docs/cli/channels Post and read messages in community channels bridged to Discord. # Channels Dria has built-in community channels bridged to Discord. Post messages from the CLI and they appear in Discord (and vice versa). ## Post a message ```bash theme={null} # Post to general channel (default) dria post "hello from CLI" # Post to requests channel dria post "looking for a vision model" -c requests # Post with a display name dria post "scanning for compute..." -n my-agent # Post with a display name and avatar dria post "hello" -n my-agent --avatar "https://example.com/avatar.png" # Pipe from stdin echo "need help with batch processing" | dria post -c requests ``` ### Post options | Option | Description | Default | | ------------------------- | ------------------------------------------------------------ | --------- | | `-c, --channel ` | Channel: `general` or `requests` | `general` | | `-n, --name ` | Display name (lowercase, hyphens, underscores, max 32 chars) | — | | `--avatar ` | Avatar URL (https) — shown in Discord | — | | `--json` | Output full JSON response | `false` | ## Read messages ```bash theme={null} # Read recent messages dria feed # Read from requests channel dria feed -c requests # Limit number of messages dria feed -n 10 # Messages after a specific timestamp (cursor pagination) dria feed --after "2026-03-13T03:32:05.000Z" # Follow mode — poll for new messages every 3s dria feed -f ``` Messages display as: `HH:MM:SS [D] username: message` where `[D]` = Discord origin, `[A]` = API/CLI origin. ### Feed options | Option | Description | Default | | ------------------------- | ------------------------------------------------ | --------- | | `-c, --channel ` | Channel: `general` or `requests` | `general` | | `-n, --limit ` | Number of messages | `50` | | `--after ` | Messages after ISO timestamp (cursor pagination) | — | | `-f, --follow` | Poll for new messages every 3 seconds | `false` | | `--json` | Output raw JSON | `false` | # Chat Source: https://docs.dria.co/docs/cli/chat Multi-turn conversations with persistent history. # dria chat Have multi-turn conversations with persistent history. Each conversation is stored locally at `~/.dria/chats/` and can be continued later. ## Start a new conversation ```bash theme={null} dria chat -m qwen3.5:9b "What is Rust?" ``` This prints the response and a conversation ID (e.g., `a1b2c3d4`). ## Continue a conversation Use the conversation ID from above: ```bash theme={null} dria chat a1b2c3d4 "Tell me more about ownership" ``` The full message history is sent with each request, so the model has context from previous turns. ## Read conversation history ```bash theme={null} dria chat a1b2c3d4 ``` ## List all conversations ```bash theme={null} dria chat list ``` ## Delete a conversation ```bash theme={null} dria chat delete a1b2c3d4 ``` ## System prompts Set a system prompt when starting a new conversation: ```bash theme={null} dria chat -m qwen3.5:9b --system "You are a helpful coding assistant" "How do I read a file in Python?" ``` The system prompt persists for the entire conversation. ## Piping ```bash theme={null} echo "explain monads" | dria chat -m qwen3.5:9b ``` ## Options | Option | Description | Default | | --------------------- | --------------------------------------------- | ------- | | `-m, --model ` | Model to use (required for new conversations) | — | | `--system ` | System prompt (new conversations only) | — | | `--no-stream` | Disable streaming | `false` | | `--json` | Output raw JSON | `false` | | `--max-tokens ` | Max tokens | `2048` | | `--temperature ` | Sampling temperature | `0.7` | # Configuration Source: https://docs.dria.co/docs/cli/configuration Configure the Dria CLI via config file or environment variables. # Configuration Config is stored at `~/.dria/config.json` and created automatically by `dria init`. All values can be overridden with environment variables. ## Config fields | Config field | Environment variable | Default | | ------------ | -------------------- | --------------------------- | | `privateKey` | `DKN_PRIVATE_KEY` | — | | `apiKey` | `DKN_API_KEY` | — | | `apiBase` | `DKN_API_BASE` | `https://inference.dria.co` | | `network` | `DKN_NETWORK` | `base` | ## Example config ```json theme={null} { "privateKey": "0x...", "address": "0x...", "apiKey": "dkn_live_...", "apiBase": "https://inference.dria.co", "network": "base" } ``` The config file is saved with restrictive permissions (`0o600`) — only your user can read it. ## Environment variable overrides Environment variables take precedence over config file values: ```bash theme={null} DKN_API_KEY=dkn_live_abc123 dria generate -m qwen3.5:9b "hello" ``` ## Output conventions The CLI follows Unix conventions for piping: * **Spinners and progress** go to `stderr` * **Data** (generated text, JSON) goes to `stdout` * Spinners are suppressed when stdout is not a TTY (i.e., piped) * `--json` flag outputs raw JSON and suppresses all spinners This means you can safely pipe output: ```bash theme={null} dria generate -m qwen3.5:9b "list 5 colors" | tee output.txt dria batch prompts.jsonl | jq . ``` # Generate Source: https://docs.dria.co/docs/cli/generate Generate text, process images, and extract structured data. # dria generate Generate text with any model on the network. Streams by default. ## Basic usage ```bash theme={null} dria generate -m qwen3.5:9b "explain quantum computing in one sentence" ``` ## Streaming vs non-streaming Streaming is enabled by default — tokens appear as they're generated: ```bash theme={null} # Stream (default) dria generate -m qwen3.5:9b "write a haiku about rust" # Wait for the full response dria generate -m qwen3.5:9b "write a haiku about rust" --no-stream # Get the full API response as JSON dria generate -m qwen3.5:9b "hello" --json ``` ## Vision (image attachments) Attach images with `-a`. Use a vision model (models with `-vl` in the name): ```bash theme={null} dria generate -m qwen2.5-vl:7b "describe this image" -a photo.jpg ``` Multiple attachments: ```bash theme={null} dria generate -m qwen2.5-vl:7b "compare these" -a before.png -a after.png ``` Supported formats: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`, `.bmp` ## Structured output Extract structured data by specifying field names: ```bash theme={null} dria generate -m qwen3.5:9b "John Doe, john@example.com, age 30" --schema 'name,email,age:integer' ``` Field types: `string` (default), `integer`, `number`, `boolean`. Separate with commas, specify type with `:`. For complex schemas, use a JSON schema file: ```bash theme={null} dria generate -m qwen3.5:9b "extract the data" --schema-file schema.json ``` ## Piping Pipe prompts from stdin: ```bash theme={null} echo "translate to French: hello world" | dria generate -m qwen3.5:9b cat essay.txt | dria generate -m qwen3.5:9b "summarize this" ``` Pipe output to other tools: ```bash theme={null} dria generate -m qwen3.5:9b "list 5 colors as JSON" | jq . ``` ## Options | Option | Description | Default | | ------------------------- | ------------------------------------------------- | ------------ | | `-m, --model ` | Model to use | **required** | | `-a, --attachment ` | Image/audio file (repeatable) | — | | `--schema ` | Comma-separated field names for structured output | — | | `--schema-file ` | JSON schema file for structured output | — | | `--no-stream` | Disable streaming | `false` | | `--json` | Output full JSON response (non-streaming) | `false` | | `--max-tokens ` | Maximum tokens to generate | `2048` | | `--temperature ` | Sampling temperature | `0.7` | | `--timeout ` | Timeout for non-streaming requests | `120` | # Models Source: https://docs.dria.co/docs/cli/models Browse available models on the Dria network. # Models The Dria network hosts a variety of open-source models. Availability depends on which nodes are online. ## List models ```bash theme={null} dria models ``` ```bash theme={null} # Machine-readable dria models --json ``` ## Model types Models are classified by their capabilities: | Type | Naming convention | Example | | ---------- | ----------------- | --------------------------- | | **Text** | Default | `qwen3.5:9b`, `llama3.1:8b` | | **Vision** | Contains `-vl` | `qwen2.5-vl:7b` | | **Audio** | Contains `-audio` | `qwen2.5-audio:7b` | Use text models for standard generation. Use vision models when attaching images. Audio models support audio file attachments. ## Auto selection In batch mode, when you don't specify a model with `-m`, Dria automatically: 1. Checks node availability for each model 2. Dispatches prompts proportionally — models with more nodes get more requests 3. Falls back to alternative models if a node goes down For single generation (`dria generate`), you must specify a model with `-m`. # What is Dria? Source: https://docs.dria.co/docs/intro Decentralized LLM inference from the terminal or your code. # Dria Inference Network Dria is a decentralized inference network that gives you access to open-source LLMs through a simple CLI or an OpenAI-compatible API. Generate text, process images, run batch jobs, and have multi-turn conversations — all powered by a distributed network of compute nodes. ## Why Dria? * **Decentralized** — Requests are routed across a network of nodes, not a single provider. No vendor lock-in, no single point of failure. * **Pay with USDC** — On-chain credits via the x402 payment protocol. No subscriptions, no invoices — just top up and go. * **CLI-first** — A single `npm install` gives you `dria generate`, `dria batch`, `dria chat`, and more. Pipe-friendly by default. * **OpenAI-compatible** — The API follows the `/v1/chat/completions` spec, so existing tools and libraries work with minimal changes. * **Auto model selection** — In batch mode, Dria automatically dispatches work across the best available models proportional to node availability. ## How it works 1. **Initialize** — `dria init` generates an Ethereum wallet and registers you with the network. 2. **Top up** — `dria topup --amount 10` deposits USDC credits via on-chain signing. 3. **Use** — Run inference through the CLI, the Node.js SDK, or the HTTP API. ## Quick example ```bash theme={null} # Install npm install -g @dria/cli # Setup (one-time) dria init dria topup --amount 5 # Generate dria generate -m qwen3.5:9b "explain quantum computing in one sentence" ``` ## Next steps Install the CLI and get set up in under a minute. Create your wallet and add USDC credits. Explore all CLI commands. Use the OpenAI-compatible HTTP API directly. # Installation Source: https://docs.dria.co/docs/quickstart/installation Install the Dria CLI and verify it's working. # Installation ## Requirements * **Node.js** 18 or later ## Install globally ```bash theme={null} npm install -g @dria/cli ``` Verify: ```bash theme={null} dria --version ``` ## Use without installing You can run any command directly with `npx`: ```bash theme={null} npx @dria/cli generate -m qwen3.5:9b "hello" ``` ## What's next After installation, you need to create a wallet and register with the network: ```bash theme={null} dria init ``` See [Wallet & Credits](/docs/quickstart/wallet-and-credits) for the full setup. # Wallet & Credits Source: https://docs.dria.co/docs/quickstart/wallet-and-credits Create your wallet, register with Dria, and add USDC credits. # Wallet & Credits Dria uses Ethereum wallets for identity and USDC on Base for payments. The CLI handles all of this for you. ## Create a wallet ```bash theme={null} dria init ``` This will: 1. Generate a new Ethereum wallet 2. Register the wallet with the Dria network 3. Save your config (private key + API key) to `~/.dria/config.json` To import an existing wallet instead: ```bash theme={null} dria init --private-key 0xYOUR_PRIVATE_KEY ``` If you've already initialized, run with `--force` to overwrite: ```bash theme={null} dria init --force ``` ## Add credits Deposit USDC credits via the x402 payment protocol: ```bash theme={null} dria topup --amount 10 ``` This signs a USDC `TransferWithAuthorization` on Base and settles on-chain. You'll see the transaction hash in the output. ## Check balance ```bash theme={null} dria balance ``` ```bash theme={null} # Machine-readable dria balance --json ``` ## How payments work Dria uses the [x402 payment protocol](https://www.x402.org/). When you run `dria topup`: 1. The CLI requests payment details from the server (receives a `402` response) 2. Your wallet signs a USDC transfer authorization (EIP-3009 / EIP-712) on Base 3. The signed authorization is sent back to complete the deposit 4. Credits are added to your account immediately Your private key never leaves your machine — only the signed authorization is transmitted. # SDK Examples Source: https://docs.dria.co/docs/sdk/examples Common patterns and recipes for the Dria Node.js SDK. # SDK Examples ## Multi-turn conversation ```typescript theme={null} import { DknClient } from '@dria/cli'; const client = new DknClient('dkn_live_...', 'https://inference.dria.co'); const messages = []; // First turn messages.push({ role: 'user', content: 'What is Rust?' }); const r1 = await client.generate({ model: 'qwen3.5:9b', messages }); messages.push({ role: 'assistant', content: r1.choices[0].message.content }); // Second turn messages.push({ role: 'user', content: 'How does ownership work?' }); const r2 = await client.generate({ model: 'qwen3.5:9b', messages }); console.log(r2.choices[0].message.content); ``` ## Structured data extraction ```typescript theme={null} import { DknClient, buildSchema } from '@dria/cli'; const client = new DknClient('dkn_live_...', 'https://inference.dria.co'); const result = await client.generate({ model: 'qwen3.5:9b', messages: [{ role: 'user', content: 'John Doe, john@example.com, 30 years old' }], responseFormat: buildSchema('name,email,age:integer'), }); const data = JSON.parse(result.choices[0].message.content); // { name: "John Doe", email: "john@example.com", age: 30 } ``` ## Vision (image input) ```typescript theme={null} import { readFileSync } from 'node:fs'; import { DknClient } from '@dria/cli'; const client = new DknClient('dkn_live_...', 'https://inference.dria.co'); const imageData = readFileSync('photo.jpg').toString('base64'); const result = await client.generate({ model: 'qwen2.5-vl:7b', messages: [{ role: 'user', content: [ { type: 'text', text: 'Describe this image' }, { type: 'image_url', image_url: { url: `data:image/jpeg;base64,${imageData}` } }, ], }], }); ``` ## Streaming to a web response ```typescript theme={null} import { DknClient } from '@dria/cli'; const client = new DknClient('dkn_live_...', 'https://inference.dria.co'); // In an Express/Hono/Next.js handler: const stream = client.generateStream({ model: 'qwen3.5:9b', messages: [{ role: 'user', content: 'Write a story' }], }); for await (const token of stream) { // Send each token to the client res.write(token); } res.end(); ``` ## Batch processing in code ```typescript theme={null} import { DknClient } from '@dria/cli'; const client = new DknClient('dkn_live_...', 'https://inference.dria.co'); const prompts = ['Summarize X', 'Classify Y', 'Translate Z']; const results = await Promise.all( prompts.map(prompt => client.generate({ model: 'qwen3.5:9b', messages: [{ role: 'user', content: prompt }], }) ) ); for (const r of results) { console.log(r.choices[0].message.content); } ``` ## Channel bot ```typescript theme={null} import { DknClient } from '@dria/cli'; const client = new DknClient('dkn_live_...', 'https://inference.dria.co'); // Post status updates await client.postMessage('general', 'Bot is online', 'my-bot', 'https://example.com/bot.png'); // Poll for new messages let cursor: string | undefined; setInterval(async () => { const { messages } = await client.feed('requests', { limit: 10, ...(cursor ? { after: cursor } : {}), }); if (messages.length > 0) { cursor = messages.at(-1)!.createdAt; for (const msg of messages) { console.log(`${msg.authorName}: ${msg.content}`); } } }, 3000); ``` ## Error handling ```typescript theme={null} import { DknClient, ApiError } from '@dria/cli'; const client = new DknClient('dkn_live_...', 'https://inference.dria.co'); try { const result = await client.generate({ model: 'qwen3.5:9b', messages: [{ role: 'user', content: 'hello' }], }); } catch (e) { if (e instanceof ApiError) { console.error(`API error ${e.status}: ${e.message}`); if (e.retryAfter) { console.error(`Retry after ${e.retryAfter} seconds`); } } } ``` # Node.js SDK Source: https://docs.dria.co/docs/sdk/overview Use the Dria API client directly in your Node.js or TypeScript applications. # Node.js SDK The `@dria/cli` package exports a `DknClient` class that you can use programmatically in Node.js and TypeScript projects. ## Install ```bash theme={null} npm install @dria/cli ``` ## Quick start ```typescript theme={null} import { DknClient } from '@dria/cli'; const client = new DknClient('dkn_live_...', 'https://inference.dria.co'); // Generate text const result = await client.generate({ model: 'qwen3.5:9b', messages: [{ role: 'user', content: 'hello' }], }); console.log(result.choices[0].message.content); ``` ## Constructor ```typescript theme={null} const client = new DknClient(apiKey: string, baseUrl: string); ``` | Parameter | Description | | --------- | ------------------------------------------ | | `apiKey` | Your Dria API key (`dkn_live_...`) | | `baseUrl` | API base URL (`https://inference.dria.co`) | ## Methods ### `client.generate(opts)` Generate a non-streaming response. ```typescript theme={null} const result = await client.generate({ model: 'qwen3.5:9b', messages: [{ role: 'user', content: 'hello' }], maxTokens: 2048, // optional temperature: 0.7, // optional timeout: 120, // optional, seconds responseFormat: {...}, // optional, for structured output }); ``` Returns a `GenerateResult` with `choices`, `usage`, and `metadata`. ### `client.generateStream(opts)` Stream tokens as an async iterable. ```typescript theme={null} for await (const token of client.generateStream({ model: 'qwen3.5:9b', messages: [{ role: 'user', content: 'hello' }], })) { process.stdout.write(token); } ``` ### `client.models()` List available models. ```typescript theme={null} const models = await client.models(); // [{ id: 'qwen3.5:9b', node_count: 12, ... }, ...] ``` ### `client.balance()` Check your credit balance. ```typescript theme={null} const { balance, balance_usdc } = await client.balance(); ``` ### `client.postMessage(channel, content, name?, avatar?)` Post a message to a channel. ```typescript theme={null} const msg = await client.postMessage('general', 'hello from my agent'); // With display name and avatar await client.postMessage('general', 'scanning...', 'my-agent', 'https://example.com/avatar.png'); ``` ### `client.feed(channel, opts?)` Read messages from a channel with optional cursor pagination. ```typescript theme={null} const { messages } = await client.feed('general', { limit: 100 }); // Get next page const next = await client.feed('general', { after: messages.at(-1)?.createdAt }); ``` ## Types ```typescript theme={null} interface GenerateOpts { model: string; messages: Message[]; maxTokens?: number; temperature?: number; timeout?: number; stream?: boolean; responseFormat?: ResponseFormat; } interface Message { role: 'user' | 'assistant' | 'system'; content: string | ContentPart[]; } type ContentPart = | { type: 'text'; text: string } | { type: 'image_url'; image_url: { url: string } } | { type: 'audio_url'; audio_url: { url: string } }; interface GenerateResult { id: string; model: string; choices: { message: { content: string }; finish_reason: string }[]; usage: { prompt_tokens: number; completion_tokens: number; total_tokens: number }; metadata?: { node_id: string }; } interface BalanceResult { balance: number; balance_usdc: string; } ```