Skip to main content

Seller configuration

A seller reads its settings from ~/.antseed/config.json (change the path with --config or ANTSEED_CONFIG). Keep non-secret settings in the file and secrets such as API keys and the identity key in environment variables. Buyer settings in the same file are covered in Buyer configuration.

You rarely need to edit the JSON by hand. antseed seller setup and the antseed config seller commands write it for you, and antseed config seller show prints the current seller section. When a setting exists in several places, a command-line flag wins over an environment variable, which wins over config.json, which wins over the built-in default.

Providers and services​

Everything a seller announces lives under seller.providers. Each key is a label you choose; plugin names the provider plugin that serves it. Each provider holds one entry per service, keyed by the service ID buyers request.

JSON
{
"seller": {
"providers": {
"inference": {
"plugin": "openai",
"baseUrl": "https://api.example-inference.com",
"defaults": {
"inputUsdPerMillion": 0.5,
"outputUsdPerMillion": 2
},
"services": {
"deepseek-v4-flash": {
"upstreamModel": "<upstream-model-id>",
"categories": ["coding"],
"pricing": {
"inputUsdPerMillion": 0.25,
"cachedInputUsdPerMillion": 0.025,
"outputUsdPerMillion": 1
},
"capabilities": {
"contextWindow": 128000,
"inputs": ["text"],
"toolUse": true
}
}
}
}
}
}
}

Provider fields​

FieldDescription
pluginPlugin name (openai, anthropic, local-llm, …) or an npm package name. Required.
baseUrlUpstream API base URL, without the /v1 suffix. Passed to the openai, local-llm, typesafe, venice-video and fal-video plugins as their *_BASE_URL setting, so you don't need to export it separately.
apiKeyEnvName of the environment variable that holds this provider's API key, so two providers on one seller can use different keys. Applies to the same plugins as baseUrl.
pathRewriteExact request paths to rewrite before forwarding upstream, for example { "/v1/chat/completions": "/v4/chat/completions" }. openai plugin only.
defaultsFallback token pricing for services that don't set their own pricing.
servicesThe services this provider announces.

Service fields​

FieldDescription
upstreamModelModel ID sent upstream. Defaults to the service ID.
pricinginputUsdPerMillion, outputUsdPerMillion and optional cachedInputUsdPerMillion, in USD per million tokens. Overrides the provider's defaults.
categoriesTags announced in discovery. Lowercase letters, digits and hyphens. Buyers can filter on any tag; privacy, legal, uncensored, coding, finance and tee are the well-known ones shown in antseed network browse --tag.
capabilitiesHints about the model. See below.
unitBillingModelsPer-image or per-video pricing. See Image and video services.

Set cachedInputUsdPerMillion when your upstream charges less for cache hits. When any seller of a model advertises a cached-input price, buyers count offers of that model that omit it at half their trust score, which can drop them below the buyer's minimum. Free offers are exempt.

Capabilities​

Capabilities tell buyers what a service can do. They are hints, not enforced limits, and an omitted field means "unknown".

FieldTypeMeaning
contextWindownumberTotal context window in tokens
maxOutputTokensnumberMaximum output tokens per response
inputsstring[]Accepted input modalities: text, image, audio, video, pdf
outputsstring[]Produced output modalities, same values
reasoningbooleanSupports reasoning effort or extended thinking
toolUsebooleanSupports tool calls
structuredOutputbooleanSupports JSON schema responses
supportedParametersstring[]Extra request-body parameters the service accepts, in lowercase snake_case (for example seed, output_format); at most 32
videoobjectOptions a video model accepts. See Image and video services

Edit the configuration from the CLI​

Add a provider. This also installs its plugin into ~/.antseed/plugins:

Terminal
antseed config seller add-provider inference \
--plugin openai \
--base-url https://api.example-inference.com \
--input 0.5 --cached 0.05 --output 2

For OpenRouter, use --base-url https://openrouter.ai/api.

Add or update a service. The provider must already exist:

Terminal
antseed config seller add-service inference kimi-k2.6 \
--upstream "<upstream-model-id>" \
--input 0.6 --cached 0.06 --output 2.5 \
--categories coding \
--capabilities '{"contextWindow":128000,"inputs":["text"],"toolUse":true,"reasoning":true}'
OptionDescription
--upstream <model>Upstream model ID (defaults to the service ID)
--input, --output, --cached <usd>Token prices in USD per million tokens
--categories <list>Comma-separated tags
--capabilities <json>Capabilities object
--unit-billing-models <json>Unit pricing, see Image and video services
--base-url <url>Sets baseUrl on the whole provider

Change single fields or remove entries:

Terminal
antseed config seller set providers.inference.services.deepseek-v4-flash.pricing.inputUsdPerMillion 0.2
antseed config seller set providers.inference.services.deepseek-v4-flash.categories '["coding","privacy"]'
antseed config seller remove-service inference kimi-k2.6
antseed config seller remove-provider inference

config seller set splits the key on dots, so it can't address a service whose ID contains a dot, such as kimi-k2.6. Use add-service again, which updates an existing service, or edit the file. set accepts keys that already exist in the file, any key under providers, and the freeTier, freeUsage and restrictedCountries keys shown below; add other blocks, such as healthCheck, by editing the file.

antseed seller setup builds the capabilities object with one question per field, tailored to the service: image services are asked about input modalities and supported parameters, text services about context window, modalities, reasoning, tool use and structured output. You can paste a JSON object at the capabilities prompt instead.

Built-in plugins and credentials​

Credentials always come from environment variables, never from config.json.

PluginServesCredential
openaiOpenAI-compatible chat and image APIsOPENAI_API_KEY
anthropicAnthropic Messages APIANTHROPIC_API_KEY
local-llmOllama or llama.cpp (default http://localhost:11434)LOCAL_LLM_API_KEY, optional
typesafeSystem One decision models (POST /v1/systemone)TYPESAFE_API_KEY
venice-videoVideo models behind the Venice video APIVENICE_VIDEO_API_KEY
fal-videofal.ai video modelsFAL_VIDEO_API_KEY
claude-code, claude-oauth, openai-responsesSubscription credentials, for testing onlyLocal keychain, OAuth token or Codex auth file

Any other npm package that exports a provider plugin works too. See Provider plugin API.

Node settings​

KeyDefaultDescription
seller.publicAddressemptyhost:port buyers should dial. Needed when the address the DHT sees isn't the one buyers can reach, such as behind a load balancer. Check it with antseed seller doctor.
seller.maxConcurrentBuyers50Maximum concurrent requests each provider plugin handles.
seller.maxUploadBodyBytes64 MiBLargest request body accepted from a buyer; at least 1 MiB. ANTSEED_MAX_UPLOAD_BODY_BYTES overrides it.
seller.restrictedCountries["CU","IR","KP","SY","RU"]Countries whose IP addresses are refused. See below.
seller.freeTiernoneRequest allowance for zero-priced services. See below.
seller.freeUsage16 requests / 15 minHow often free usage is recorded on-chain. See below.
seller.healthCheckenabled, 5 min, 3 failuresModel health checks. See below.
seller.gasCheckenabled, 60 s, 0.00005 ETHPauses advertising while the seller wallet holds less ETH than minBalanceEth, checking every intervalMs (at least 10 s). Resumes once funded.
seller.verifiersnoneVerifier SDKs to run provers for. See TEE seller.
seller.verificationsnoneDomain and GitHub ownership claims. See Verified identity.
seller.agentDirnoneAnt agent directory. See below.
identity.displayNamederived from peer IDName shown to buyers.
Terminal
antseed config set identity.displayName "Example Inference"
antseed config seller set publicAddress "peer.example.com:6882"

Free-tier limits​

A service is free when its token prices and all unit-billing prices are zero. Free services are unlimited unless you set seller.freeTier, which applies one allowance across all free services, per buyer address, per IP, or both:

JSON
{
"seller": {
"freeTier": {
"maxRequestsPerAddress": 100,
"maxRequestsPerIp": 300,
"windowMs": 86400000
}
}
}

Set at least one of the two limits. windowMs is a sliding window (default 24 hours, minimum 1000). A request is served only while every configured limit has room, and only served requests count. Counters are stored in the seller's metering.db, survive restarts, and are shared across all free services. When a buyer runs out, the seller answers HTTP 429 with code: "free_tier_exhausted", a limitedBy field (address or ip) and a Retry-After header. Paid services are unaffected.

LimitKeyed onCaveat
maxRequestsPerAddressBuyer identity addressA user can create another identity
maxRequestsPerIpConnecting IP, IPv6 grouped by /64Users behind one NAT share it; a seller behind a proxy sees the proxy's IP

When you set both, set the IP limit higher so a shared network isn't cut off by one heavy user. Use nonzero pricing when you need stronger protection.

Terminal
antseed config seller set freeTier.maxRequestsPerAddress 100
antseed config seller set freeTier.maxRequestsPerIp 300

Remove seller.freeTier to make free services unlimited again.

Restricted countries​

By default the seller refuses connections from IP addresses in Cuba, Iran, North Korea, Syria and Russia. The lookup uses the bundled geoip-country database, so no buyer address leaves the seller. It is best effort: buyers behind a VPN are seen at the VPN's address. A refused buyer gets "This seller does not accept connections from your location.", and GET /metadata returns 403 with the same text.

Terminal
antseed config seller set restrictedCountries '["CU","IR","KP","SY","RU"]'
antseed config seller set restrictedCountries '[]' # turn the check off

Free-usage records​

Free requests are still recorded on-chain so buyers earn usage credit, and the seller pays the gas. The seller writes a record once recordBatchSize free requests have accumulated on a channel, or recordFlushIntervalMs after the first unrecorded one, whichever comes first, and always before the channel's deadline. Larger values mean fewer transactions; usage is written later, never dropped.

Terminal
antseed config seller set freeUsage.recordBatchSize 64
antseed config seller set freeUsage.recordFlushIntervalMs 3600000

Both must be positive integers; recordFlushIntervalMs must be at least 1000. The free-usage flow itself is described in Payments.

Model health checks​

The seller probes each text service at startup and every intervalMs afterwards. After failureThreshold consecutive failures it stops advertising the service, and advertises it again when a probe succeeds. Image and video services are never probed, because a probe would generate a paid result.

JSON
{
"seller": {
"healthCheck": { "enabled": true, "intervalMs": 300000, "failureThreshold": 3 }
}
}

Ant agent​

An ant agent wraps your service with a persona, guardrails, on-demand knowledge and custom tools. Point agentDir at a directory containing an agent.json manifest, or map service IDs to directories, with "*" as the fallback:

JSON
{
"seller": {
"agentDir": {
"kimi-k2.6": "./agents/coding",
"*": "./agents/default"
}
}
}

Relative paths resolve from the config file's directory. See Provider plugin API and the @antseed/ant-agent README for the manifest format.

Payment settings​

KeyDefaultDescription
payments.crypto.chainIdbase-mainnetbase-mainnet, base-sepolia or base-local
payments.crypto.rpcUrlpublic Base RPCYour Base JSON-RPC endpoint. See Base RPC.
payments.minBudgetPerRequest"10000" ($0.01)Minimum USDC per request, in base units
payments.minSettleDelta"2000" ($0.002)Smallest unsettled amount, in base units, for which the idle settle loop sends a transaction. Closing a channel always settles the full amount. seller start --min-settle-delta 0.002 overrides it in USDC.
payments.serveWhileClosePendingfalseKeep serving channels whose buyer already requested a close on-chain. Work served this way can become uncollectible.
payments.sellerContract.addressnoneAn on-chain seller contract that fronts this peer. Buyers check that your peer address is an operator of the contract.
relayer.enabledtrueRelay buyers' gasless deposit sweeps with your seller wallet and earn the relay fee
relayer.minProfitBaseUnits"0"Minimum profit (relay fee minus estimated gas), in USDC base units
relayer.maxInFlight2Concurrent sweep submissions
relayer.maxPerPeerPerMinute6Sweep requests accepted per buyer per minute

How earnings reach you is covered in Seller payments.

ANTS staking settings​

antseed ants and the seller staking commands find the recognized-usage contracts from the built-in deployment record for payments.crypto.chainId and from the on-chain AntseedRegistry, so nothing needs configuring on Base mainnet. Two optional settings live under payments.crypto:

KeyDescription
explorerApiUrlAntscan base URL used for pool statistics, volume history, seller profiles and closed positions. Defaults to https://antscan.co. Set it to "" to read only the chain, which lists only the pools you stake in.
<contract>AddressPer-contract overrides for local or test deployments: sellerRegistryAddress, sellerPoolsAddress, sellerPoolsRewardsAddress, usageAccountingAddress, usageRewardsAddress, emissionsGateAddress, positionInitAddress, washTradingRegistryAddress, pointsPolicyRegistryAddress, antsTokenAddress, legacyEmissionsContractAddress, legacyStakingContractAddress. positionInitAddress has no on-chain pointer and must be set explicitly outside the built-in deployments.

Environment variables​

Environment variables hold secrets and per-run overrides. The seller-relevant ones are ANTSEED_IDENTITY_HEX, ANTSEED_PASSPHRASE, the plugin credentials above, ANTSEED_BASE_RPC_URL, ANTSEED_SETTLEMENT_IDLE_MS (idle time before settling, default 10 minutes), ANTSEED_MAX_UPLOAD_BODY_BYTES and ANTSEED_VERIFIER_SDKS. See Flags and environment variables for the full list.