",
"receivedAt": "2026-04-04T09:21:35.218Z",
"from": { "email": "john@gmail.com", "name": "John Snow" },
"to": { "hash": "a1b2c3d4e5f6..." },
"subject": "Alert: Server down",
"text": "Server #3 is not responding",
"html": "Server #3 is not responding
",
"headers": {},
"attachments": [
{
"filename": "attachment.pdf",
"contentType": "application/pdf",
"size": 33380,
"downloadUrl": "",
"downloadUrlExpiresAt": "2026-04-04T09:26:35.218Z"
}
]
}
```
### Payload Fields
[Section titled “Payload Fields”](#payload-fields)
| Field | Type | Description |
| ------------------- | ----------------- | ---------------------------------------- |
| `externalMessageId` | string | Unique identifier for the email message |
| `receivedAt` | string (ISO 8601) | When the email was received |
| `from` | object | Sender: `email` and optional `name` |
| `to` | object | Recipient: `hash` (SHA256 of your token) |
| `subject` | string | Email subject line |
| `text` | string | Plain text body |
| `html` | string | HTML body (if present) |
| `headers` | object | Raw email headers as key-value pairs |
| `attachments` | array | File attachments (empty array if none) |
### Attachment Fields
[Section titled “Attachment Fields”](#attachment-fields)
| Field | Type | Description |
| ---------------------- | ----------------- | -------------------------------------- |
| `filename` | string | Original filename |
| `contentType` | string | MIME type |
| `size` | integer | File size in bytes |
| `downloadUrl` | string | Presigned URL to download the file |
| `downloadUrlExpiresAt` | string (ISO 8601) | When the download URL expires (1 hour) |
Note
**Cost:** 1 credit per email processed (in addition to webhook operation costs).
Note
Use the `to.hash` field to verify that incoming webhook requests originate from echoValue without exposing your raw token.
# OpenAPI Specification
> Download and use the echoValue OpenAPI 3.0 specification
The echoValue API is fully documented using the **OpenAPI 3.0** specification format.
## Download
[Section titled “Download”](#download)
📥 **[Download openapi.yaml](/openapi.yaml)**
## View & Test Interactively
[Section titled “View & Test Interactively”](#view--test-interactively)
**Swagger UI:** [Open in Swagger UI](https://petstore.swagger.io/?url=https://docs.echovalue.dev/openapi.yaml)
***
## Use Cases
[Section titled “Use Cases”](#use-cases)
### Generate Client SDKs
[Section titled “Generate Client SDKs”](#generate-client-sdks)
Use [OpenAPI Generator](https://openapi-generator.tech/) to generate client libraries:
```sh
openapi-generator-cli generate \
-i https://docs.echovalue.dev/openapi.yaml \
-g javascript \
-o ./echovalue-client
```
Supported languages include Java, Ruby, PHP, C#, TypeScript, Rust, and [many more](https://openapi-generator.tech/docs/generators).
### Import into API Tools
[Section titled “Import into API Tools”](#import-into-api-tools)
| Tool | Steps |
| ------------ | ---------------------------------------------- |
| **Postman** | File → Import → Link → Paste OpenAPI URL |
| **Insomnia** | Create → Import From → URL → Paste OpenAPI URL |
| **Paw** | File → Import → Paste OpenAPI URL |
| **HTTPie** | Import → OpenAPI → Paste OpenAPI URL |
### API Validation in Tests
[Section titled “API Validation in Tests”](#api-validation-in-tests)
```js
// Example with jest-openapi
const jestOpenAPI = require('jest-openapi');
jestOpenAPI('https://docs.echovalue.dev/openapi.yaml');
test('GET /default/mykey returns valid response', async () => {
const response = await fetch('https://api.echovalue.dev/kv/default/mykey', {
headers: { 'x-token': 'mytoken' }
});
expect(response).toSatisfyApiSpec();
});
```
### Mock Server
[Section titled “Mock Server”](#mock-server)
```sh
# Using Prism
npx @stoplight/prism-cli mock \
https://docs.echovalue.dev/openapi.yaml
# Mock server runs at http://127.0.0.1:4010
```
***
The OpenAPI specification is automatically updated with each documentation release. Always use the latest version from:
****
Note
The specification is version-controlled alongside the documentation. Check the [GitHub repository](https://github.com/njoylab/docs.echovalue.dev) for the full history of changes.
# Response Headers
> Standard response headers returned by the echoValue API
Every API response includes these headers:
| Header | Type | Description |
| ----------- | ------- | --------------------------------------------------- |
| `x-cost` | integer | Credits deducted from your wallet for this request |
| `x-balance` | integer | Credits remaining in your wallet after this request |
Note
`x-balance` is the most efficient way to monitor your balance — it’s included on every response at no extra cost, so you don’t need to call the balance endpoint separately.
## Reading Headers
[Section titled “Reading Headers”](#reading-headers)
* cURL
```sh
# Use -i to show response headers
curl -i 'https://api.echovalue.dev/kv/default/mykey' \
-H 'x-token: mytoken'
# Output includes:
# x-cost: 1
# x-balance: 99
```
* JavaScript
```js
fetch('https://api.echovalue.dev/kv/default/mykey', {
headers: { 'x-token': 'mytoken' }
})
.then(response => {
console.log('Cost:', response.headers.get('x-cost'));
console.log('Balance:', response.headers.get('x-balance'));
return response.text();
});
```
* Python
```python
import requests
response = requests.get('https://api.echovalue.dev/kv/default/mykey',
headers={'x-token': 'mytoken'}
)
print('Cost:', response.headers.get('x-cost'))
print('Balance:', response.headers.get('x-balance'))
```
* PHP
```php
```
* Go
```go
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.echovalue.dev/kv/default/mykey", nil)
req.Header.Set("x-token", "mytoken")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Cost:", resp.Header.Get("x-cost"))
fmt.Println("Balance:", resp.Header.Get("x-balance"))
}
```
# Token Management
> Generate, check balance, and recharge your echoValue API token
## Generate Token
[Section titled “Generate Token”](#generate-token)
`POST https://api.echovalue.dev/token`
Generates a new API token. No authentication required.
**Request body** (`application/x-www-form-urlencoded`):
| Parameter | Value | Description |
| --------- | ----- | -------------------------------- |
| `token` | `new` | Must be the literal string `new` |
**Response:** `200` — The new token as plain text.
```plaintext
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
```
* cURL
```sh
curl 'https://api.echovalue.dev/token' \
-d 'token=new'
```
* JavaScript
```js
fetch('https://api.echovalue.dev/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'token=new'
})
.then(response => response.text())
.then(token => console.log(token));
```
* Python
```python
import requests
response = requests.post('https://api.echovalue.dev/token',
data={'token': 'new'}
)
print(response.text)
```
* PHP
```php
```
* Go
```go
package main
import (
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader("token=new")
resp, _ := http.Post("https://api.echovalue.dev/token", "application/x-www-form-urlencoded", body)
defer resp.Body.Close()
token, _ := io.ReadAll(resp.Body)
println(string(token))
}
```
Note
New tokens include **100 free credits**.
Note
**Rate limit:** 1 request every 10 seconds.
Caution
Tokens unused for two years are automatically deactivated and all associated data is deleted.
***
## Check Wallet Balance
[Section titled “Check Wallet Balance”](#check-wallet-balance)
`GET https://api.echovalue.dev/token`
Returns remaining credits and token metadata.
**Request headers:**
| Header | Description |
| --------- | -------------- |
| `x-token` | Your API token |
**Response:** `200` — JSON object.
```json
{
"wallet": 12345,
"created": "2023-08-09T15:40:09.77Z",
"hash": "a1b2c3d4e5f6..."
}
```
| Field | Type | Description |
| --------- | ----------------- | --------------------------------------------------------------------------------- |
| `wallet` | integer | Remaining credit balance |
| `created` | string (ISO 8601) | Date when the token was created |
| `hash` | string | SHA256 hash of your token — use this in webhook payloads instead of the raw token |
* cURL
```sh
curl 'https://api.echovalue.dev/token' \
-H 'x-token: mytoken'
```
* JavaScript
```js
fetch('https://api.echovalue.dev/token', {
headers: { 'x-token': 'mytoken' }
})
.then(response => response.json())
.then(data => console.log(data));
```
* Python
```python
import requests
response = requests.get('https://api.echovalue.dev/token',
headers={'x-token': 'mytoken'}
)
print(response.json())
```
* PHP
```php
```
* Go
```go
package main
import (
"encoding/json"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.echovalue.dev/token", nil)
req.Header.Set("x-token", "mytoken")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result map[string]interface{}
json.Unmarshal(body, &result)
println(result)
}
```
Note
**Cost:** 1 credit. For ongoing balance monitoring, use the `x-balance` response header instead — it’s available on every request at no extra cost.
***
## Recharge Wallet
[Section titled “Recharge Wallet”](#recharge-wallet)
`GET https://api.echovalue.dev/recharge`
Returns a Stripe payment link to add credits to your wallet.
**Request headers:**
| Header | Description |
| --------- | -------------- |
| `x-token` | Your API token |
**Query parameters:**
| Parameter | Type | Description | Default |
| --------- | ------ | ----------------------------------------------------------------- | ------- |
| `amount` | string | Number of million operations to add. Accepted values: `1` or `3`. | `1` |
**Response:** `200` — Stripe payment URL as plain text.
```plaintext
https://buy.stripe.com/?client_reference_id=mytoken
```
* cURL
```sh
curl 'https://api.echovalue.dev/recharge?amount=1' \
-H 'x-token: mytoken'
```
* JavaScript
```js
fetch('https://api.echovalue.dev/recharge?amount=1', {
headers: { 'x-token': 'mytoken' }
})
.then(response => response.text())
.then(url => window.open(url));
```
* Python
```python
import requests
response = requests.get('https://api.echovalue.dev/recharge',
headers={'x-token': 'mytoken'},
params={'amount': '1'}
)
print(response.text)
```
* PHP
```php
```
* Go
```go
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.echovalue.dev/recharge?amount=1", nil)
req.Header.Set("x-token", "mytoken")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
```
Follow the returned URL to complete the payment.
Note
The card transaction will appear as **nJoyLab** on your statement.