Meter API Reference
Solenoid Meter exposes atomic balance operations over a standard REST API.
Base URL
https://api.solenoid.systems/v1
Authentication
All endpoints require a Bearer token. See Authentication.
Headers
Request:
Authorization: Bearer sm_xxx— required on all requestsContent-Type: application/json— required on POST requests
Response:
X-Request-Id— unique request identifier on every responseX-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset— included on429responses only
See Rate Limits.
Self-Service Endpoints
Operate on your own account balance.
GET /v1/meter/balance
Check your current credit balance.
curl https://api.solenoid.systems/v1/meter/balance \
-H "Authorization: Bearer sm_your_key_here"
{
"balance": 1000,
"user_id": "usr_abc123"
}
| Field | Type | Description |
|---|---|---|
balance | integer | Current credit balance |
user_id | string | Your user ID |
Multi-Tenant Endpoints
Manage end-user meters at /v1/meter/:meterId/*. Each meterId is alphanumeric with dashes and underscores, max 64 characters. Meters are created implicitly on first use.
Each multi-tenant call deducts 1 credit from your developer account.
GET /v1/meter/:meterId/balance
Get the balance of an end-user meter.
curl https://api.solenoid.systems/v1/meter/user-123/balance \
-H "Authorization: Bearer sm_your_key_here"
{
"balance": 500,
"meter_id": "user-123"
}
| Field | Type | Description |
|---|---|---|
balance | integer | Current meter balance |
meter_id | string | The meter ID from the URL |
POST /v1/meter/:meterId/deduct
Atomically deduct credits from an end-user meter. Fails with 402 if the balance is insufficient.
curl -X POST https://api.solenoid.systems/v1/meter/user-123/deduct \
-H "Authorization: Bearer sm_your_key_here" \
-H "Content-Type: application/json" \
-d '{"amount": 5}'
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | integer | Yes | Credits to deduct (positive integer) |
{
"balance": 495,
"meter_id": "user-123"
}
POST /v1/meter/:meterId/refill
Add credits to an end-user meter.
curl -X POST https://api.solenoid.systems/v1/meter/user-123/refill \
-H "Authorization: Bearer sm_your_key_here" \
-H "Content-Type: application/json" \
-d '{"amount": 100}'
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | integer | Yes | Credits to add (positive integer) |
{
"balance": 600,
"meter_id": "user-123"
}
POST /v1/meter/:meterId/reset
Reset an end-user meter to a specific balance.
curl -X POST https://api.solenoid.systems/v1/meter/user-123/reset \
-H "Authorization: Bearer sm_your_key_here" \
-H "Content-Type: application/json" \
-d '{"balance": 1000}'
| Parameter | Type | Required | Description |
|---|---|---|---|
balance | integer | Yes | Balance to set (non-negative integer) |
{
"balance": 1000,
"meter_id": "user-123"
}
Key Management
POST /v1/keys/rotate
Rotate your API key. The old key remains valid for 7 days.
curl -X POST https://api.solenoid.systems/v1/keys/rotate \
-H "Authorization: Bearer sm_old_key_here"
{
"key": "sm_new_key_here",
"rotated_at": "2026-02-01T12:00:00Z",
"expires_at": "2026-02-08T12:00:00Z"
}
| Field | Type | Description |
|---|---|---|
key | string | New API key (starts with sm_) |
rotated_at | string | ISO 8601 timestamp of rotation |
expires_at | string | When the old key stops working |
Both keys deduct from the same balance. Max one rotation per hour.
Metering
| Operation | Cost |
|---|---|
| GET /v1/meter/balance | Free |
| Multi-tenant balance read | Free |
| Multi-tenant deduct/refill/reset | 1 credit |
| Key rotation | 1 credit |
Error Responses
See Error Format for the shared error schema.
All errors return a JSON object with a nested error field:
{
"error": {
"code": "error_code",
"message": "Human-readable description"
}
}
| Status | Code | Meaning |
|---|---|---|
400 | validation_error | Invalid input — check the fields object for details |
401 | unauthorized | Missing or invalid API key |
402 | insufficient_balance | Not enough credits for the operation |
404 | not_found | Invalid route |
429 | rate_limit_exceeded | Too many requests — back off and retry |
500 | internal_error | Server error — retry or contact support |
For the full error code list, see Meter Errors.
Idempotency
Multi-tenant /v1/meter/:meterId/* endpoints are not idempotent by default. Retrying a failed request may cause duplicate deductions or refills. Check balance before and after operations to verify success.
Versioning
The API uses URL path versioning (/v1/). When breaking changes ship, a new version (/v2/) will be released. Old versions are supported for 12 months after deprecation.