This is the abridged developer documentation for Ethos API # Introduction > Welcome to the official API documentation for Ethos Network. This documentation provides detailed information about the Ethos API endpoints,… Welcome to the official API documentation for Ethos Network. This documentation provides detailed information about the Ethos API endpoints, request/response formats, and data models. These docs are available at ## Getting Started [Section titled “Getting Started”](#getting-started) Ethos offers a comprehensive RESTful API that allows developers to interact with the Ethos Network. The API is organized around standard HTTP methods and uses standard HTTP response codes. ### Whitepaper [Section titled “Whitepaper”](#whitepaper) For a complete overview of the Ethos Network, including its mechanisms and governance model, please refer to the [Ethos Whitepaper](https://whitepaper.ethos.network). ### Base URL [Section titled “Base URL”](#base-url) All API requests should be made to the following base URL: ```plaintext https://api.ethos.network ``` ### Authentication [Section titled “Authentication”](#authentication) Some API endpoints require authentication using a Privy token. These are usually endpoints meant to be used in the context of an active user session — for example, when performing actions tied to the currently logged-in user. If authentication is required, you must include a valid token in the Authorization header: ```http Authorization: Bearer ``` The token is stored in a `privy-token` cookie under the `app.ethos.network` domain. Note, this token is short-lived and expires after 1 hour. #### ⚠️ Important notes: [Section titled “⚠️ Important notes:”](#️-important-notes) * Most developers won’t need to use this token directly — many endpoints are public or free to use. * Tokens are tied to the current user session and are only needed when working within that user’s authenticated context. #### API Keys [Section titled “API Keys”](#api-keys) For programmatic access (bots, scripts, CI/CD), you can create long-lived API keys using a [SIWE](https://eips.ethereum.org/EIPS/eip-4361) signature. See [API Keys](/api-documentation/api-key-authentication) for a quick start and full reference. ### Client Identification [Section titled “Client Identification”](#client-identification) To help us monitor and manage usage across different integrations, all API requests must include the `X-Ethos-Client` header. This header should contain the name of your product or integration, and may optionally include a version number (e.g., `my-app` or `my-app@1.0.0`). ```http X-Ethos-Client: my-cool-app@1.2.3 ``` Caution Required: Requests without this header may be subject to rate limiting. Including this header helps us: * Attribute traffic to your app * Diagnose issues faster * Ensure fair and efficient resource allocation ### Ethos Everywhere Wallet [Section titled “Ethos Everywhere Wallet”](#ethos-everywhere-wallet) Ethos Everywhere Wallet brings Ethos functionality into partner applications, allowing users to post reviews, vote, and reply directly from those apps without wallet popups or manual transaction signing. This creates a seamless user experience while maintaining security through server-side managed wallets. **For Partners:** * To integrate Ethos Everywhere Wallet into your application, see the [Ethos Everywhere Wallet Partner Guide](/api-documentation/ethos-everywhere-wallet-integration) * Becoming an allowlisted partner requires domain verification and a security review * Gas sponsorship is available for qualified users based on credibility score * Endpoints require JWT authentication; authentication status and wallet balance is available via API * All wallet endpoints are documented in the [API v2 reference](api-documentation/api-v2/) under the “wallets” tag ### LLM-ready Documentation [Section titled “LLM-ready Documentation”](#llm-ready-documentation) Ethos API documentation is LLM-optimized, enabling AI-powered developer tools like ChatGPT, Claude, Cursor, GitHub Copilot, and other LLM assistants to retrieve accurate, contextual responses. Developers can ask questions like *“How do I get the score for a specific profile?”* or *“What’s the structure of an activity object?”* — and receive precise answers powered by our official API documentation. #### Resources [Section titled “Resources”](#resources) * **OpenAPI v3 spec**\ The full schema of our public API in OpenAPI format, including available endpoints, methods, parameters, and response structures.\ 👉 * **LLM discovery files** These files help large language models find the right endpoint without reading the full reference. They are generated from the OpenAPI spec and follow the llms.txt convention: * — endpoint groups with a one-line description each * — every endpoint with parameters and response shapes ### Userkeys [Section titled “Userkeys”](#userkeys) Some APIs accept a `userkey` as a user identifier. Below are the supported formats: | Format | Description | | ----------------------------------- | ----------------------------------------------------------------------------- | | `profileId:` | Ethos profile IDExample: `profileId:10` | | `address:
` | Ethereum addressExample: `address:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045` | | `service:discord:` | Discord user IDExample: `service:discord:797130033613242441` | | `service:telegram:` | Telegram user IDExample: `service:telegram:167380455` | | `service:x.com:` | Twitter (x.com) user IDExample: `service:x.com:295218901` | | `service:x.com:username:` | Twitter (x.com) usernameExample: `service:x.com:username:VitalikButerin` | # Agents and x402 > Call the Ethos API from an AI agent: free with a client header, or paid per request in USDC over x402 with no sign-up at all. Ethos reputation data is open. An agent can read it two ways: * **Free, with a header.** Every read endpoint under `https://api.ethos.network/api/v2` answers any caller that sends `X-Ethos-Client: `. No key, no account. This is the whole API, documented on this site, and it is the way to go for anything beyond a one-off lookup. [Vibe Coding Quickstart](/api-documentation/vibe-coding-quickstart) is written for an agent to read. * **Paid per request, with x402.** A handful of the most useful lookups are also served at `https://developers.ethos.network/x402/…` for `$0.001` in USDC on Base per call, using the [x402](https://x402.org) protocol. These exist so the API is listed where agents look for tools (Coinbase’s x402 Bazaar, x402scan and other indexes only list resources that answer `402 Payment Required`). An agent with an x402-capable client and a wallet needs no setup at all. The data is identical. Pay only if your agent already pays for tools that way. ## The x402 routes [Section titled “The x402 routes”](#the-x402-routes) | Route | Returns | Same as | | ---------------------------------------- | ---------------------------------------------------- | --------------------------------------------- | | `GET /x402/score/{userkey}` | Credibility score and level | `GET /api/v2/score/userkey` | | `GET /x402/user/x/{handle}` | The Ethos profile behind an X handle or account id | `GET /api/v2/user/by/x/{accountIdOrUsername}` | | `GET /x402/user/address/{address}` | The Ethos profile behind an EVM address | `GET /api/v2/user/by/address/{address}` | | `GET /x402/users/search?query=…&limit=…` | Profiles matching a name, handle or address fragment | `GET /api/v2/users/search` | | `GET /x402/xp/{userkey}` | Total XP across all seasons | `GET /api/v2/xp/user/{userkey}` | A `userkey` names a person any way Ethos knows them: `address:0x…`, `profileId:1`, `service:x.com:username:ethos_network`, `service:x.com:`, `service:discord:` or `service:telegram:`. Machine-readable descriptions of the routes: * `https://developers.ethos.network/.well-known/x402`, the discovery document crawlers read. * `https://developers.ethos.network/openapi.json`, an OpenAPI 3.1 document for just these routes (also at `/x402/openapi.json`). ## How a paid call works [Section titled “How a paid call works”](#how-a-paid-call-works) 1. Request the route with no payment. The answer is `402 Payment Required`; its `PAYMENT-REQUIRED` header (and the JSON body) carry the price, the USDC contract on Base, the address to pay and, under `extensions.bazaar`, what the route takes and returns. 2. Sign a USDC transfer for that amount (EIP-3009, so the payer needs no ETH for gas) and send the same request again with it in the `PAYMENT-SIGNATURE` header. 3. The facilitator verifies and settles it on Base; the response is the lookup, with a `PAYMENT-RESPONSE` header carrying the transaction. Any x402 client does all of this for you: * TypeScript ```typescript import { wrapFetchWithPayment, x402Client } from "@x402/fetch"; import { registerExactEvmScheme } from "@x402/evm/exact/client"; import { privateKeyToAccount } from "viem/accounts"; // A wallet holding a little USDC on Base, Polygon or Arbitrum. const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY"); const client = registerExactEvmScheme(new x402Client(), { signer: account }); const fetchWithPay = wrapFetchWithPayment(fetch, client); const res = await fetchWithPay( "https://developers.ethos.network/x402/score/service:x.com:username:ethos_network", ); console.log(await res.json()); // { score: 2441, level: "revered" } console.log(res.headers.get("PAYMENT-RESPONSE")); // the settlement, base64 JSON ``` * curl (just the 402) ```sh curl -i https://developers.ethos.network/x402/score/service:x.com:username:ethos_network # HTTP/2 402 # PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Mi… ← base64 JSON: price, asset, payTo, extensions.bazaar ``` * Free instead ```sh curl "https://api.ethos.network/api/v2/score/userkey?userkey=service:x.com:username:ethos_network" \ -H "X-Ethos-Client: my-agent" # {"score":2441,"level":"revered"} ``` ## Details [Section titled “Details”](#details) * **Networks and asset:** USDC, `exact` scheme, `$0.001` per request, on Base (`eip155:8453`), Polygon (`eip155:137`) and Arbitrum (`eip155:42161`); pay on whichever your wallet holds USDC on. The 402’s `accepts` lists every option; do not hard-code the price or the network. * **Facilitator:** Coinbase’s CDP facilitator settles the payments. The payer pays no gas. * **Rate limits and errors:** the same as the free API, whose status codes and bodies are passed through unchanged. A rejected payment is a fresh `402` whose body says why (for example, not enough USDC in the wallet). * **No API key is ever issued** by the x402 routes, and they never write anything. For writes (reviews, vouches, XP tips) use [API keys](/api-documentation/api-key-authentication) with the free API. # API Keys > Create API keys for programmatic access to the Ethos API from bots, scripts, and integrations. API keys let you call any profile-scoped Ethos endpoint without a browser session. You sign a one-time [SIWE](https://eips.ethereum.org/EIPS/eip-4361) message with your wallet, receive a key, and include it in the `X-Ethos-Api-Key` header on every request. **Prerequisites:** an [Ethos profile](https://app.ethos.network) linked to your wallet, and API key access enabled for your account. ## Quick start [Section titled “Quick start”](#quick-start) Create a key, send an XP tip, revoke the key — all in one script. Or try the [interactive playground](https://trust-ethos.github.io/api-docs/playground/) to run each step in your browser. * TypeScript ```typescript import { privateKeyToAccount } from "viem/accounts"; import { createSiweMessage } from "viem/siwe"; const API = "https://api.ethos.network/api/v2"; const CLIENT = "my-bot@1.0.0"; // identifies your app const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY"); // --- 1. Create API key --- const message = createSiweMessage({ domain: "api.ethos.network", address: account.address, statement: "Create Ethos API key", uri: "https://api.ethos.network", version: "1", chainId: 8453, // Base nonce: crypto.randomUUID().replaceAll("-", ""), issuedAt: new Date(), expirationTime: new Date(Date.now() + 10 * 60 * 1000), // must be within 10 min }); const signature = await account.signMessage({ message }); const keyResp = await fetch(`${API}/api-keys`, { method: "POST", headers: { "Content-Type": "application/json", "X-Ethos-Client": CLIENT }, body: JSON.stringify({ address: account.address, message, signature, name: "my-bot", }), }); if (!keyResp.ok) throw new Error(`Create key failed: ${await keyResp.text()}`); const { id: keyId, token } = await keyResp.json(); console.log("Key created:", keyId); // --- 2. Send XP tip --- const tipResp = await fetch(`${API}/xp/tip`, { method: "POST", headers: { "Content-Type": "application/json", "X-Ethos-Api-Key": token, "X-Ethos-Client": CLIENT, }, body: JSON.stringify({ receiverUserkey: "profileId:1", amount: 5, message: "5 XP, 10 lines of code — developers.ethos.network", }), }); if (!tipResp.ok) throw new Error(`Tip failed: ${await tipResp.text()}`); const tip = await tipResp.json(); console.log(`Tip #${tip.tipId} sent. Balance: ${tip.senderNewBalance} XP`); // --- 3. Revoke key --- const revokeResp = await fetch(`${API}/api-keys/${keyId}`, { method: "DELETE", headers: { "X-Ethos-Api-Key": token, "X-Ethos-Client": CLIENT }, }); if (!revokeResp.ok) throw new Error(`Revoke failed: ${await revokeResp.text()}`); console.log("Key revoked"); ``` * Python ```python from datetime import datetime, timedelta, timezone from eth_account import Account from eth_account.messages import encode_defunct from siwe import SiweMessage import requests, secrets API = "https://api.ethos.network/api/v2" CLIENT = "my-bot@1.0.0" # identifies your app account = Account.from_key("0xYOUR_PRIVATE_KEY") now = datetime.now(timezone.utc) # --- 1. Create API key --- msg = SiweMessage( domain="api.ethos.network", address=account.address, statement="Create Ethos API key", uri="https://api.ethos.network", version="1", chain_id=8453, # Base nonce=secrets.token_hex(16), issued_at=now.isoformat(), expiration_time=(now + timedelta(minutes=10)).isoformat(), # must be within 10 min ) message_text = msg.prepare_message() signature = "0x" + account.sign_message( encode_defunct(text=message_text) ).signature.hex() key_resp = requests.post(f"{API}/api-keys", headers={"X-Ethos-Client": CLIENT}, json={ "address": account.address, "message": message_text, "signature": signature, "name": "my-bot", }, ) key_resp.raise_for_status() data = key_resp.json() token, key_id = data["token"], data["id"] print(f"Key created: {key_id}") # --- 2. Send XP tip --- tip_resp = requests.post(f"{API}/xp/tip", headers={"X-Ethos-Api-Key": token, "X-Ethos-Client": CLIENT}, json={ "receiverUserkey": "profileId:1", "amount": 5, "message": "5 XP, 10 lines of code — developers.ethos.network", }, ) tip_resp.raise_for_status() tip = tip_resp.json() print(f"Tip #{tip['tipId']} sent. Balance: {tip['senderNewBalance']} XP") # --- 3. Revoke key --- revoke_resp = requests.delete( f"{API}/api-keys/{key_id}", headers={"X-Ethos-Api-Key": token, "X-Ethos-Client": CLIENT}, ) revoke_resp.raise_for_status() print("Key revoked") ``` * curl ```bash PRIVATE_KEY="0xYOUR_PRIVATE_KEY" ADDRESS=$(cast wallet address "$PRIVATE_KEY") API="https://api.ethos.network/api/v2" CLIENT="my-bot@1.0.0" NONCE=$(openssl rand -hex 16) NOW=$(date -u '+%Y-%m-%dT%H:%M:%SZ') # macOS: date -u -v+10M Linux: date -u -d "+10 min" EXP=$(date -u -v+10M '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null \ || date -u -d "+10 min" '+%Y-%m-%dT%H:%M:%SZ') # --- 1. Create API key --- MESSAGE="api.ethos.network wants you to sign in with your Ethereum account: ${ADDRESS} Create Ethos API key URI: https://api.ethos.network Version: 1 Chain ID: 8453 Nonce: ${NONCE} Issued At: ${NOW} Expiration Time: ${EXP}" SIGNATURE=$(cast wallet sign --private-key "$PRIVATE_KEY" "$MESSAGE") KEY_JSON=$(curl -s -X POST "$API/api-keys" \ -H "Content-Type: application/json" \ -H "X-Ethos-Client: $CLIENT" \ -d "{ \"address\": \"${ADDRESS}\", \"message\": $(printf '%s' "$MESSAGE" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))"), \"signature\": \"${SIGNATURE}\", \"name\": \"my-bot\" }") TOKEN=$(echo "$KEY_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])") KEY_ID=$(echo "$KEY_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])") echo "Key created: $KEY_ID" # --- 2. Send XP tip --- curl -s -X POST "$API/xp/tip" \ -H "Content-Type: application/json" \ -H "X-Ethos-Api-Key: $TOKEN" \ -H "X-Ethos-Client: $CLIENT" \ -d '{ "receiverUserkey": "profileId:1", "amount": 5, "message": "5 XP, 10 lines of code — developers.ethos.network" }' # --- 3. Revoke key --- curl -s -X DELETE "$API/api-keys/$KEY_ID" \ -H "X-Ethos-Api-Key: $TOKEN" \ -H "X-Ethos-Client: $CLIENT" echo "Key revoked" ``` ## Creating a key [Section titled “Creating a key”](#creating-a-key) Key creation uses a SIWE (Sign-In with Ethereum) signature to prove wallet ownership. The server verifies the signature and returns a JWT-based API key. ### SIWE message requirements [Section titled “SIWE message requirements”](#siwe-message-requirements) | Field | Value | Notes | | ---------------- | --------------------------- | ---------------------------------------------------------------------------------------- | | `domain` | `api.ethos.network` | Must match exactly | | `chainId` | `8453` | Base mainnet | | `expirationTime` | Within 10 minutes | Required — messages without it are rejected | | `nonce` | Random hex string | Single-use — the server rejects replayed nonces. Generate a fresh one for every request. | | `uri` | `https://api.ethos.network` | | | `version` | `1` | | ### Request: `POST /api/v2/api-keys` [Section titled “Request: POST /api/v2/api-keys”](#request-post-apiv2api-keys) | Field | Type | Required | Description | | ----------- | ------ | -------- | --------------------------------------------------- | | `address` | string | Yes | Your Ethereum address (0x-prefixed, checksummed) | | `message` | string | Yes | The SIWE message you signed | | `signature` | string | Yes | ECDSA signature (0x-prefixed, 132 hex chars) | | `name` | string | Yes | Label for this key (1-100 chars) | | `expiresAt` | string | No | ISO 8601 datetime. Default: 90 days. Max: 365 days. | ### Response [Section titled “Response”](#response) ```json { "id": "cm...", "token": "ethos_eyJhbGci...", "name": "my-bot", "expiresAt": "2026-06-25T00:00:00.000Z" } ``` Caution The `token` is only returned once. There is no way to retrieve it later. Store it securely immediately. ## Authenticating requests [Section titled “Authenticating requests”](#authenticating-requests) Include the key in the `X-Ethos-Api-Key` header on every request: ```http X-Ethos-Api-Key: ethos_eyJhbGci... X-Ethos-Client: my-bot@1.0.0 ``` The key authenticates as the Ethos profile that created it. All profile-scoped endpoints (tips, reviews, votes, vouches) work the same way they do with browser session auth. ## Revoking a key [Section titled “Revoking a key”](#revoking-a-key) ```plaintext DELETE /api/v2/api-keys/{id} ``` Pass the `id` returned when you created the key. Revocation takes effect immediately — subsequent requests with the revoked key return `401 Unauthorized`. You can revoke a key using the key itself (as shown in the quick start) or with browser session auth. ## Reference [Section titled “Reference”](#reference) ### Key lifecycle [Section titled “Key lifecycle”](#key-lifecycle) | Property | Value | | ----------------------- | --------------------------------------------------------------- | | Default expiry | 90 days | | Maximum expiry | 365 days | | Active keys per profile | 25 | | Usage tracking | `lastUsedAt` updated per request (throttled to once per minute) | ### Endpoints [Section titled “Endpoints”](#endpoints) | Method | Path | Auth | | -------- | ----------------------- | ----------------------------- | | `POST` | `/api/v2/api-keys` | None (SIWE signature in body) | | `GET` | `/api/v2/api-keys` | API key or browser session | | `DELETE` | `/api/v2/api-keys/{id}` | API key or browser session | ### Error codes [Section titled “Error codes”](#error-codes) | HTTP | Code | Meaning | | ---- | -------------------- | ------------------------------------------- | | 400 | `INVALID_AMOUNT` | XP tip amount must be a positive integer | | 400 | `CANNOT_TIP_SELF` | Sender and receiver are the same profile | | 400 | `INSUFFICIENT_XP` | Not enough XP in your balance | | 401 | — | Invalid, expired, or revoked API key | | 403 | — | API key access not enabled for this profile | | 404 | `RECEIVER_NOT_FOUND` | No Ethos user matches the receiver userkey | | 404 | `KEY_NOT_FOUND` | Key ID not found or not owned by you | # API v1 (deprecated) > This documentation was generated by AI and is guaranteed to be incorrect and out of date. It is here only as an example reference so people can explore. The… ### ⚠️ Generated by LLM [Section titled “⚠️ Generated by LLM”](#️-generated-by-llm) This documentation was generated by AI and *is guaranteed to be incorrect* and *out of date*. It is here only as an example reference so people can explore. The Ethos APIs are still evolving rapidly. Danger 🚨 Ethos is not responsible if you mess up your account or lose money because you used this API documentation. ### API Overview [Section titled “API Overview”](#api-overview) The Ethos API is organized into the following sections: * [**Contracts**](/api-documentation/api-v1-deprecated/contracts): Get contract addresses * [**Contributions**](/api-documentation/api-v1-deprecated/contributions): Manage user contributions * [**Markets**](/api-documentation/api-v1-deprecated/markets): Access reputation market data * [**Replies**](/api-documentation/api-v1-deprecated/replies): Query comment replies * [**Scores**](/api-documentation/api-v1-deprecated/scores): Access user credibility scores and history * [**Signatures**](/api-documentation/api-v1-deprecated/signatures): Handle creation of signed messages (attestations, addresses, slashes) * [**Slashes**](/api-documentation/api-v1-deprecated/slashes): Query and manage slashes * [**Users**](/api-documentation/api-v1-deprecated/users): Access user data and statistics * [**Vouches**](/api-documentation/api-v1-deprecated/vouches): Query and manage vouches between users # Contracts > The Contracts API provides information about the deployed addresses of core Ethos smart contracts on the blockchain. ## Overview [Section titled “Overview”](#overview) The Contracts API provides information about the deployed addresses of core Ethos smart contracts on the blockchain. ## Endpoints [Section titled “Endpoints”](#endpoints) ### Get Smart Contract Addresses [Section titled “Get Smart Contract Addresses”](#get-smart-contract-addresses) ```plaintext GET /api/v1/contracts ``` **Description**: Retrieves addresses of Ethos smart contracts deployed on the blockchain. **Authentication Required**: No ### Parameters [Section titled “Parameters”](#parameters) #### Query Parameters [Section titled “Query Parameters”](#query-parameters) | Name | Type | Required | Description | | ----------------- | ------ | -------- | ---------------------------------------------- | | `targetContracts` | string | Yes | Must be set to “all” to retrieve all contracts | ### Responses [Section titled “Responses”](#responses) #### Success Response [Section titled “Success Response”](#success-response) **Code**: 200 OK ```json { "ok": true, "data": [ { "name": "attestation", "configAddress": "0x27499D9A439D1c7B4538f247625cc7aA159D3c14", "managedAddress": "0x27499D9A439D1c7B4538f247625cc7aA159D3c14", "isProxy": true }, { "name": "contractAddressManager", "configAddress": "0xC31252d6bE0252018F1b12deF25f6582dB0f3E9a", "managedAddress": "0xC31252d6bE0252018F1b12deF25f6582dB0f3E9a", "isProxy": false }, // Additional contracts... ] } ``` | Property | Type | Description | | ----------------------- | ------- | ----------------------------------------------- | | `ok` | boolean | Success status | | `data` | array | Array of contract objects | | `data[].name` | string | Name of the smart contract | | `data[].configAddress` | string | Configured Ethereum address of the contract | | `data[].managedAddress` | string | Address managed by the contract address manager | | `data[].isProxy` | boolean | Whether the contract uses a proxy pattern | #### Error Response [Section titled “Error Response”](#error-response) **Code**: 400 Bad Request ```json { "ok": false, "error": { "code": "VALIDATION_ERROR", "message": "Validation error", "fields": [ { "code": "invalid_union", "message": "Invalid input", "path": ["targetContracts"], "unionErrors": [ { "issues": [ { "code": "invalid_literal", "expected": "all", "message": "Invalid literal value, expected \"all\"", "path": ["targetContracts"] } ], "name": "ZodError" } ] } ] } } ``` ### Example [Section titled “Example”](#example) #### Request [Section titled “Request”](#request) ```bash http GET "https://api.ethos.network/api/v1/contracts?targetContracts=all" ``` ### Notes [Section titled “Notes”](#notes) * The API currently only supports retrieving all contracts with `targetContracts=all`. * The implementation suggests support for specifying an array of specific contracts, but this doesn’t appear to work in the current version. * The returned contracts include core Ethos functionality such as Profile, Attestation, Review, Vote, and Vouch contracts. * Use these addresses to directly interact with Ethos smart contracts via Web3 libraries or blockchain explorers. # Contributions > The Contributions API provides endpoints for retrieving information about user contribution activities, bundles, and statistics within the Ethos network.… ## Overview [Section titled “Overview”](#overview) The Contributions API provides endpoints for retrieving information about user contribution activities, bundles, and statistics within the Ethos network. These contributions often involve tasks like performing trust checks, reviewing content, or participating in scoring. ## Endpoints [Section titled “Endpoints”](#endpoints) ### Get Contribution Stats by User Key [Section titled “Get Contribution Stats by User Key”](#get-contribution-stats-by-user-key) ```plaintext GET /api/v1/contributions/:userkey/stats ``` **Description**: Retrieves contribution statistics for a specific user key (profile or address). **Authentication Required**: No #### Parameters [Section titled “Parameters”](#parameters) **Path Parameters** | Name | Type | Required | Description | | --------- | ------ | -------- | --------------------------------------------------------- | | `userkey` | string | Yes | The user key (e.g., `profileId:123`, `address:0xabc...`). | **Query Parameters** None **Request Body** None #### Responses [Section titled “Responses”](#responses) **Success Response** **Code**: 200 OK ```json { "ok": true, "data": { "canGenerateDailyContributions": boolean, "resetTimestamp": number, "totalCount": number, "completedCount": number, "skippedCount": number, "pendingCount": number, "pendingBundleCount": number, "todayXp": number, "totalXp": number, "streakDays": number, "streakDaysOptimistic": number, "leaderboardRank": number | null } } ``` | Property | Type | Description | | ------------------------------------ | -------------- | ----------------------------------------------------------------------- | | `ok` | boolean | Indicates if the API call itself was successful. | | `data` | object | Container for the contribution statistics. | | `data.canGenerateDailyContributions` | boolean | Whether the user can generate new daily contributions. | | `data.resetTimestamp` | number | Unix timestamp when the daily contributions reset. | | `data.totalCount` | number | Total number of contributions assigned. | | `data.completedCount` | number | Number of completed contributions. | | `data.skippedCount` | number | Number of skipped contributions. | | `data.pendingCount` | number | Number of pending contributions. | | `data.pendingBundleCount` | number | Number of pending contribution bundles. | | `data.todayXp` | number | XP earned from contributions today. | | `data.totalXp` | number | Total XP earned from contributions all time. | | `data.streakDays` | number | Current contribution streak in days (confirmed). | | `data.streakDaysOptimistic` | number | Current contribution streak assuming today is completed (for UI). | | `data.leaderboardRank` | number \| null | User’s rank on the contribution XP leaderboard (or null if not ranked). | **Error Responses** **Code**: 400 Bad Request ```json { "error": "Invalid user key format", "code": "VALIDATION_ERROR" } ``` **Code**: 404 Not Found ```json { "error": "User not found", "code": "NOT_FOUND" } ``` #### Example [Section titled “Example”](#example) **Request** ```bash http GET https://api.ethos.network/api/v1/contributions/profileId:1/stats ``` **Response** ```json { "ok": true, "data": { "canGenerateDailyContributions": true, "resetTimestamp": 1743379200000, "totalCount": 0, "completedCount": 0, "skippedCount": 0, "pendingCount": 0, "pendingBundleCount": 0, "todayXp": 0, "totalXp": 5243475, "streakDays": 0, "streakDaysOptimistic": 0, "leaderboardRank": 1 } } ``` #### Notes [Section titled “Notes”](#notes) * Authentication is not required. * User key can be based on profile ID or address. * Response details match the `ContributionStats` type from `@ethos/domain`. *** ### Perform Contribution Action [Section titled “Perform Contribution Action”](#perform-contribution-action) ```plaintext POST /api/v1/contributions/action ``` **Description**: Submits an action (e.g., answer, skip, review submission) for a specific contribution item. **Authentication Required**: Yes (Requires Privy Session and Profile) #### Parameters [Section titled “Parameters”](#parameters-1) **Path Parameters** None **Query Parameters** None **Request Body** ```json { "id": number, // Contribution ID "action": { "type": "SKIP | REVIEW | TRUST_BATTLE | TRUST_CHECK | REVIEW_CHECK | SCORE_CHECK", // Additional fields based on type: // "txHash": string, (for REVIEW) // "chosenIndex": number, (for TRUST_BATTLE) // "answer": "POSITIVE | NEGATIVE | NEUTRAL | UNSURE" (for *CHECK types) } } ``` | Property | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `id` | number | Yes | The ID of the contribution being acted upon. | | `action` | object | Yes | The action object. | | `action.type` | string | Yes | The type of action being performed. | | `action.txHash` | string | Optional | Transaction hash (required for `REVIEW` type). | | `action.chosenIndex` | number | Optional | The index chosen by the user (required for `TRUST_BATTLE` type). | | `action.answer` | string | Optional | The user’s answer (required for `TRUST_CHECK`, `REVIEW_CHECK`, `SCORE_CHECK` types). Must be one of `POSITIVE`, `NEGATIVE`, `NEUTRAL`, `UNSURE`. | #### Responses [Section titled “Responses”](#responses-1) **Success Response** **Code**: 200 OK / 204 No Content (Needs verification) ```json // Likely returns empty body on success { "ok": true } ``` | Property | Type | Description | | -------- | ------- | ------------------------------------------------ | | `ok` | boolean | Indicates if the API call itself was successful. | **Error Responses** **Code**: 400 Bad Request ```json { "ok": false, "error": { "code": "VALIDATION_ERROR | CONTRIBUTION_NOT_PENDING | EXPIRED_CONTRIBUTION_BUNDLE | INCORRECT_CONTRIBUTION_ORDER | CONTRIBUTION_TYPE_MISMATCH | ...", "message": "Specific error message (e.g., Invalid input, Contribution not pending, etc.)" } } ``` **Code**: 401 Unauthorized ```json { "ok": false, "error": { "code": "UNAUTHORIZED | NO_ETHOS_PROFILE", "message": "Authentication required or no Ethos profile linked" } } ``` **Code**: 404 Not Found ```json { "ok": false, "error": { "code": "MISSING_CONTRIBUTION", "message": "Contribution not found" } } ``` #### Example [Section titled “Example”](#example-1) **Request (Skip Action)** ```bash # Needs auth token http POST https://api.ethos.network/api/v1/contributions/action \ Authorization:"Bearer " \ id:=1001 \ action:='{"type":"SKIP"}' ``` **Request (Trust Check Action)** ```bash # Needs auth token http POST https://api.ethos.network/api/v1/contributions/action \ Authorization:"Bearer " \ id:=1002 \ action:='{"type":"TRUST_CHECK", "answer":"POSITIVE"}' ``` **Response** ```json # Needs actual example response (likely empty or simple ok) { "ok": true } ``` #### Notes [Section titled “Notes”](#notes-1) * This endpoint requires authentication. * Used to progress through daily contribution tasks. * Specific errors are returned for various conditions (expired bundle, wrong order, already completed, etc.). * Need to confirm exact success response (body/status code). *** ### Generate Daily Contributions [Section titled “Generate Daily Contributions”](#generate-daily-contributions) ```plaintext POST /api/v1/contributions/daily ``` **Description**: Generates the next set of daily contribution tasks for the authenticated user if they are eligible, or returns the existing daily tasks if already generated. **Authentication Required**: Yes (Requires Privy Session and Profile) #### Parameters [Section titled “Parameters”](#parameters-2) None #### Responses [Section titled “Responses”](#responses-2) **Success Response** **Code**: 200 OK Returns an object containing an array of the user’s daily contribution bundle IDs. ```json { "ok": true, "data": { "contributionBundleIds": [number] // Array of Bundle IDs for the current day } } ``` | Property | Type | Description | | ---------------------------- | ------- | ------------------------------------------------------------------------------------------------------- | | `ok` | boolean | Indicates if the API call itself was successful. | | `data` | object | Container for the response data. | | `data.contributionBundleIds` | Array | An array containing the ID(s) of the contribution bundle(s) generated or retrieved for the current day. | **Error Responses** **Code**: 401 Unauthorized ```json { "ok": false, "error": { "code": "UNAUTHORIZED | NO_ETHOS_PROFILE", "message": "Authentication required or no Ethos profile linked" } } ``` **Code**: 409 Conflict ```json { "ok": false, "error": { "code": "DAILY_TASKS_CREATION_IN_PROGRESS", "message": "Daily tasks creation is already in progress" // From Redis lock } } ``` **Code**: 500 Internal Server Error ```json { "ok": false, "error": { "code": "INTERNAL_SERVER_ERROR", // Or other specific codes from lock/DB errors "message": "Failed to generate daily contributions" } } ``` #### Example [Section titled “Example”](#example-2) **Request** ```bash # Needs auth token http POST https://api.ethos.network/api/v1/contributions/daily \ Authorization:"Bearer " ``` **Response (New Bundles Generated)** ```json # Needs actual example response { "ok": true, "data": { "contributionBundleIds": [502, 503, 504] // Example IDs } } ``` **Response (Bundles Already Existed)** ```json # Needs actual example response { "ok": true, "data": { "contributionBundleIds": [502, 503, 504] // Same IDs as previously generated today } } ``` #### Notes [Section titled “Notes”](#notes-2) * Requires authentication. * Creates the next set of tasks for the user if none exist for the current UTC day. * If tasks already exist for the day, it returns the existing bundle IDs. * Uses a Redis lock to prevent concurrent generation attempts, returning a 409 Conflict if locked. *** # Markets > The Markets API provides endpoints for interacting with Ethos prediction markets. This includes a market's transaction history and the market holdings of an… ## Overview [Section titled “Overview”](#overview) The Markets API provides endpoints for interacting with Ethos prediction markets. This includes a market’s transaction history and the market holdings of an address. ## Endpoints [Section titled “Endpoints”](#endpoints) ### Get Market Transaction History [Section titled “Get Market Transaction History”](#get-market-transaction-history) ```plaintext GET /api/v1/markets/:profileId/tx/history ``` **Description**: Retrieves the transaction history for a specific market based on its associated profile ID. **Authentication Required**: No #### Parameters [Section titled “Parameters”](#parameters) **Path Parameters** | Name | Type | Required | Description | | ----------- | ------- | -------- | ------------------------------------------------------------- | | `profileId` | integer | Yes | Profile ID of the market to retrieve transaction history for. | #### Responses [Section titled “Responses”](#responses) **Success Response** **Code**: 200 OK Returns an array of transaction history objects, each containing the transaction hash, timestamp, type, and amount.\ Returns a paginated list of transaction history objects for the specified market. ```json { "ok": true, "data": [ { "txHash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", "timestamp": "2025-03-30T10:00:00.000Z", "type": "BUY", "amountWei": "1000000000000000000" }, { "txHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "timestamp": "2025-03-29T14:30:00.000Z", "type": "SELL", "amountWei": "500000000000000000" }, // ... more transaction history objects ] "data": { "values": [ { "eventId": 851534, "marketId": 8, "actorAddress": "0x57E5D96c50ceE6bFa0Fc12dD7892Cf50B5892e91", "type": "SELL", "voteType": "trust", "votes": 17, "funds": "111418815322905231", "txHash": "0x1b833c4fa432df3b0bef27df41fcd993bc903f147b0ba9ebcf3c82ef0005353c", "timestamp": 1743213959 }, { "eventId": 844872, "marketId": 8, "actorAddress": "0x7B3D5e9Ab82D3390792793468854975004440Cf6", "type": "SELL", "voteType": "trust", "votes": 45, "funds": "296984191472517380", "txHash": "0xbd7d708ab9b979b0499ef148f5ad940643610982d01cd42530809b5e9223bbdd", "timestamp": 1743188997 } // ... more transaction objects ], "total": 150, "limit": 50, "offset": 0 } } ``` | Property | Type | Description | | ---------------------------- | ------- | -------------------------------------------------------- | | `ok` | boolean | Success status | | `data` | array | Array of transaction history objects | | `data[].txHash` | string | Transaction hash | | `data[].timestamp` | string | Timestamp of the transaction (ISO 8601 format) | | `data[].type` | string | Transaction type (BUY or SELL) | | `data[].amountWei` | string | Transaction amount in wei | | `data` | object | Paginated response object | | `data.values` | array | Array of transaction history objects | | `data.values[].eventId` | integer | Unique identifier for the event | | `data.values[].marketId` | integer | Profile ID of the market | | `data.values[].actorAddress` | string | Ethereum address of the actor performing the transaction | | `data.values[].type` | string | Transaction type (BUY or SELL) | | `data.values[].voteType` | string | Type of vote (trust or distrust) | | `data.values[].votes` | integer | Number of votes involved in the transaction | | `data.values[].funds` | string | Transaction amount in wei | | `data.values[].txHash` | string | Transaction hash | | `data.values[].timestamp` | integer | Timestamp of the transaction (Unix timestamp) | | `data.total` | integer | Total number of transactions available | | `data.limit` | integer | Maximum number of transactions returned in this response | | `data.offset` | integer | Number of transactions skipped (for pagination) | **Error Response** **Code**: 404 Not Found (Example: Market not found) ```json { "ok": false, "error": { "code": "NOT_FOUND", "message": "Market not found" } } ``` #### Example [Section titled “Example”](#example) **Request** ```bash http GET https://api.ethos.network/api/v1/markets/1/tx/history ``` #### Notes [Section titled “Notes”](#notes) * This endpoint is useful for fetching transaction history data for a specific market when its profile ID is known. * If the requested `profileId` does not correspond to an existing market, the request will fail with a 404 error. * The transaction history data is sorted by timestamp in descending order. * Pagination parameters (`limit`, `offset`) can be added as query parameters (e.g., `?limit=10&offset=20`). The default limit is likely 50, offset 0. * A `voteTypeFilter` query parameter can be used to filter by ‘trust’ or ‘distrust’. ### Get Address Market Holdings [Section titled “Get Address Market Holdings”](#get-address-market-holdings) ```plaintext GET /api/v1/markets/holdings/:address ``` **Description**: Retrieves the market holdings for a specific Ethereum address. **Authentication Required**: No #### Parameters [Section titled “Parameters”](#parameters-1) **Path Parameters** | Name | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------- | | `address` | string | Yes | Ethereum address to retrieve market holdings for. | #### Responses [Section titled “Responses”](#responses-1) **Success Response** **Code**: 200 OK Returns an array of market holding objects, each containing the market profile ID, balance in wei, and market information. ```json { "ok": true, "data": [ { "marketProfileId": 1, "balanceWei": "10000000000000000000", "market": { "marketProfileId": 1, "creatorAddress": "0x9E2218375567BB466b81E38E1a8b599b6250408C", "positivePrice": "13394648448485010", "negativePrice": "6605351551514990", "trustVotes": 1717, "distrustVotes": 16, "createdAt": "2024-09-14T00:00:00.000Z", "updatedAt": "2025-03-30T04:35:04.439Z", "basePrice": "10000000000000000", "creationCost": "100000000000000000", "liquidity": "1000", "configType": "NORMAL", "profile": { "primaryAddress": "0x9E2218375567BB466b81E38E1a8b599b6250408C", "avatarUrl": "https://pbs.twimg.com/profile_images/1797826077194096640/d_YEoB8n.jpg", "ethosScore": 1711, "name": "Ethos", "twitterUsername": "ethos_network" }, "stats": { "marketCapWei": "7836838875288201409", "volumeTotalWei": "11279993864858341235", "volume24hWei": "10606200508522432", "priceChange24hPercent": 0 } } }, { "marketProfileId": 8, "balanceWei": "5000000000000000000", "market": { // ... market information for market profile ID 8 } }, // ... more market holding objects ] } ``` | Property | Type | Description | | ------------------------ | ------- | ------------------------------- | | `ok` | boolean | Success status | | `data` | array | Array of market holding objects | | `data[].marketProfileId` | integer | Profile ID of the market | | `data[].balanceWei` | string | Balance of the holder in wei | | `data[].market` | object | Market information | **Error Response** **Code**: 400 Bad Request (Example: Invalid address) ```json { "ok": false, "error": { "code": "VALIDATION_ERROR", "message": "Validation error", "fields": [ { "code": "invalid_address", "message": "Invalid Ethereum address", "path": ["address"] } ] } } ``` #### Example [Section titled “Example”](#example-1) **Request** ```bash http GET https://api.ethos.network/api/v1/markets/holdings/0x9E2218375567BB466b81E38E1a8b599b6250408C ``` #### Notes [Section titled “Notes”](#notes-1) * This endpoint is useful for fetching market holding data for a specific Ethereum address. * If the requested `address` is not a valid Ethereum address, the request will fail with a 400 error. * The market holding data is sorted by balance in descending order. # Replies > The Replies API allows querying replies associated with specific contracts and parent IDs, as well as retrieving summaries of reply counts and user… ## Overview [Section titled “Overview”](#overview) The Replies API allows querying replies associated with specific contracts and parent IDs, as well as retrieving summaries of reply counts and user participation. ## Endpoints [Section titled “Endpoints”](#endpoints) ### Get Reply Summaries [Section titled “Get Reply Summaries”](#get-reply-summaries) ```plaintext POST /api/v1/reply/summary ``` **Description**: Retrieves a summary of replies for specific target contracts and parent IDs, including the total count and whether the current user has participated in the discussion. **Authentication Required**: No ### Parameters [Section titled “Parameters”](#parameters) #### Request Body [Section titled “Request Body”](#request-body) | Name | Type | Required | Description | | ---------------------- | --------------- | -------- | --------------------------------------------------------- | | `targetContract` | string | Yes | Ethereum address of the target contract | | `parentIds` | array | Yes | Array of parent IDs to fetch reply summaries for | | `currentUserProfileId` | integer or null | No | Profile ID of the current user to check for participation | ### Responses [Section titled “Responses”](#responses) #### Success Response [Section titled “Success Response”](#success-response) **Code**: 200 OK ```json { "ok": true, "data": { "0x2820b3aB3543ADB80810f11F2651f0DD9A04E801": { "1": { "count": 0, "participated": false } } } } ``` | Property | Type | Description | | --------------------------------------------- | ------- | ------------------------------------------------------------------- | | `ok` | boolean | Success status | | `data` | object | Map of target contracts to parent IDs to reply summaries | | `data[targetContract]` | object | Map of parent IDs to reply summaries for a specific target contract | | `data[targetContract][parentId]` | object | Reply summary for a specific parent ID | | `data[targetContract][parentId].count` | integer | Total number of replies | | `data[targetContract][parentId].participated` | boolean | Whether the current user has participated in the discussion | #### Error Response [Section titled “Error Response”](#error-response) **Code**: 400 Bad Request ```json { "ok": false, "error": { "code": "VALIDATION_ERROR", "message": "Validation error", "fields": [ { "code": "invalid_type", "expected": "number", "message": "Expected number, received nan", "path": ["currentUserProfileId"], "received": "nan" } ] } } ``` ### Example [Section titled “Example”](#example) #### Request [Section titled “Request”](#request) ```bash http POST "https://api.ethos.network/api/v1/reply/summary" \ targetContract=0x2820b3aB3543ADB80810f11F2651f0DD9A04E801 \ parentIds:='[1]' \ currentUserProfileId:=null ``` ### Notes [Section titled “Notes”](#notes) * The reply summary endpoint provides an efficient way to get the total number of replies and participation status without fetching all the individual replies. * The structure of the response allows querying multiple target contracts and parent IDs in a single request. * When `currentUserProfileId` is `null`, the `participated` field will always be `false`. # Scores > The Scores API allows you to query and analyze credibility scores in the Ethos network. Scores represent a user's trustworthiness and reputation based on… ## Overview [Section titled “Overview”](#overview) The Scores API allows you to query and analyze credibility scores in the Ethos network. Scores represent a user’s trustworthiness and reputation based on their activity, reviews, vouches, and other factors. The API provides endpoints for retrieving individual scores, score history, comparing scores, and even simulating changes to a score. ## Endpoints [Section titled “Endpoints”](#endpoints) ### Get Score [Section titled “Get Score”](#get-score) ```plaintext GET /api/v1/score/:userkey ``` **Description**: Retrieves the credibility score for a specific user. **Authentication Required**: No #### Parameters [Section titled “Parameters”](#parameters) **Path Parameters** | Name | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------- | | `userkey` | string | Yes | The userkey for the user. Can be in the format of “profileId:123”, “address:0x1234…”, or “service:x.com:username:vitalii” | **Query Parameters** | Name | Type | Required | Description | | -------- | ------ | -------- | -------------------------------------------------------------------------------------- | | `txHash` | string | No | Transaction hash to retrieve a historical score associated with a specific transaction | #### Responses [Section titled “Responses”](#responses) **Success Response** **Code**: 200 OK ```json { "ok": true, "data": { "score": 1711, "elements": { "Ethereum Address Age": { "element": { "name": "Ethereum Address Age", "type": "LookupInterval", "ranges": [ {"end": 90, "score": 0}, {"start": 90, "end": 365, "score": 1}, {"start": 365, "end": 1461, "score": 3}, {"start": 1461, "end": 2922, "score": 5}, {"start": 2922, "score": 5} ], "outOfRangeScore": 0 }, "raw": 0, "weighted": 0, "error": false }, "Twitter Account Age": { "element": { "name": "Twitter Account Age", "type": "LookupInterval", "ranges": [ {"start": 0, "end": 90, "score": -250}, {"start": 90, "end": 365, "score": -50}, {"start": 365, "end": 730, "score": 0}, {"start": 1461, "score": 5} ], "outOfRangeScore": 0 }, "raw": 1178, "weighted": 0, "error": false }, "Number of Vouchers Impact": { "element": { "name": "Number of Vouchers Impact", "type": "LookupNumber", "range": {"min": 0, "max": 270} }, "raw": 94, "weighted": 94, "error": false }, "Vouched Ethereum Impact": { "element": { "name": "Vouched Ethereum Impact", "type": "LookupNumber", "range": {"min": 0, "max": 270} }, "raw": 223, "weighted": 223, "error": false }, "Review Impact": { "element": { "name": "Review Impact", "type": "LookupNumber", "range": {"min": -800, "max": 270} }, "raw": 193, "weighted": 193, "error": false } }, "metadata": {}, "errors": [] } } ``` | Property | Type | Description | | ------------------------------------------- | ------- | ----------------------------------------------------------- | | `ok` | boolean | Success status | | `data` | object | Score data | | `data.score` | number | Overall credibility score (ranging from 0-2800) | | `data.elements` | object | Detailed information about each score component | | `data.elements[elementName]` | object | Information about a specific score element | | `data.elements[elementName].element` | object | Definition of the score element | | `data.elements[elementName].element.name` | string | Element name | | `data.elements[elementName].element.type` | string | Element type (LookupInterval or LookupNumber) | | `data.elements[elementName].element.ranges` | array | For LookupInterval: ranges with start, end and score values | | `data.elements[elementName].element.range` | object | For LookupNumber: min and max range values | | `data.elements[elementName].raw` | number | Raw score value for this element | | `data.elements[elementName].weighted` | number | Weighted contribution to the final score | | `data.elements[elementName].error` | boolean | Whether there was an error calculating this element | | `data.metadata` | object | Additional metadata about the score calculation | | `data.errors` | array | Names of elements that had errors during calculation | **Error Responses** **Code**: 404 Not Found ```json { "ok": false, "error": { "code": "NOT_FOUND", "message": "Score not found" } } ``` ```json { "ok": false, "error": { "code": "NOT_FOUND", "message": "Attestation account not found" } } ``` ```json { "ok": false, "error": { "code": "NOT_FOUND", "message": "Score for transaction not found" } } ``` #### Example [Section titled “Example”](#example) **Request** ```bash http GET https://api.ethos.network/api/v1/score/profileId:1 ``` **Response** ```json { "ok": true, "data": { "score": 1711, "elements": { "Ethereum Address Age": { "element": { "name": "Ethereum Address Age", "type": "LookupInterval", "ranges": [ {"end": 90, "score": 0}, {"start": 90, "end": 365, "score": 1}, {"start": 365, "end": 1461, "score": 3}, {"start": 1461, "end": 2922, "score": 5}, {"start": 2922, "score": 5} ], "outOfRangeScore": 0 }, "raw": 0, "weighted": 0, "error": false }, "Number of Vouchers Impact": { "element": { "name": "Number of Vouchers Impact", "type": "LookupNumber", "range": {"min": 0, "max": 270} }, "raw": 94, "weighted": 94, "error": false } }, "metadata": {}, "errors": [] } } ``` #### Notes [Section titled “Notes”](#notes) * Ethos credibility scores range from 0-2800 and are categorized into levels: * Untrusted: 0-799 * Questionable: 800-1199 * Neutral: 1200-1599 * Reputable: 1600-1999 * Exemplary: 2000-2800 * The response includes detailed information about each component that contributes to the final score. * The `elements` object contains various factors like account age, review impact, voucher count, etc. * Each element includes its raw score, weighted contribution, and metadata about how it was calculated. * If a user has no historical data for a particular element, it may show a raw score of 0. *** ### Simulate Score Changes [Section titled “Simulate Score Changes”](#simulate-score-changes) ```plaintext POST /api/v1/score/simulate ``` **Description**: Simulates how various actions would affect a user’s credibility score. **Authentication Required**: No #### Parameters [Section titled “Parameters”](#parameters-1) **Request Body** ```json { "subjectKey": "profileId:1", "vouchAmount": 1.5, "numberOfVouchers": 2 } ``` | Property | Type | Required | Description | | ------------------------ | ---------------- | -------- | ------------------------------------------------------------------- | | `subjectKey` | string | Yes | Userkey of the subject to simulate the score for | | `twitterUserId` | string | No | Twitter user ID to simulate account age impact | | `reviews` | array of objects | No | Array of reviews to simulate | | `reviews[].author` | string | Yes | Address of the review author | | `reviews[].score` | string | Yes | Review score: “positive”, “neutral”, or “negative” | | `vouchAmount` | number | No | Amount of ETH to simulate being vouched | | `vouchedDays` | number | No | Number of days to simulate the vouch for (default: maximum allowed) | | `numberOfVouchers` | number | No | Number of vouchers to simulate | | `votes` | object | No | Votes to simulate | | `votes.review` | object | No | Votes on reviews | | `votes.review.upvotes` | number | Yes | Number of upvotes on reviews | | `votes.review.downvotes` | number | Yes | Number of downvotes on reviews | | `votes.vouch` | object | No | Votes on vouches | | `votes.vouch.upvotes` | number | Yes | Number of upvotes on vouches | | `votes.vouch.downvotes` | number | Yes | Number of downvotes on vouches | | `slashes` | array of objects | No | Slashes to simulate | | `slashes[].type` | string | Yes | Type of slash: “SOCIAL” or “FINANCIAL” | | `slashes[].amount` | number | Yes | Amount of the slash | #### Responses [Section titled “Responses”](#responses-1) **Success Response** **Code**: 200 OK ```json { "ok": true, "data": { "simulation": { "value": 38.70023504412825, "relativeValue": 38.70023504412825, "impact": "POSITIVE", "adjustedRecipientScore": 1749.7002350441282 }, "calculationResults": { "score": 1749.7002350441282, "elements": { "Ethereum Address Age": { "element": { "name": "Ethereum Address Age", "type": "LookupInterval", "ranges": [ {"end": 90, "score": 0}, {"start": 90, "end": 365, "score": 1}, {"start": 365, "end": 1461, "score": 3}, {"start": 1461, "end": 2922, "score": 5}, {"start": 2922, "score": 5} ], "outOfRangeScore": 0 }, "raw": 0, "weighted": 0, "error": false }, "Twitter Account Age": { "element": { "name": "Twitter Account Age", "type": "LookupInterval", "ranges": [ {"start": 0, "end": 90, "score": -250}, {"start": 90, "end": 365, "score": -50}, {"start": 365, "end": 730, "score": 0}, {"start": 1461, "score": 5} ], "outOfRangeScore": 0 }, "raw": 463, "weighted": 0, "error": false }, "Vouched Ethereum Impact": { "element": { "name": "Vouched Ethereum Impact", "type": "LookupNumber", "range": {"min": 0, "max": 270} }, "raw": 253.3720080769059, "weighted": 253.3720080769059, "error": false }, "Number of Vouchers Impact": { "element": { "name": "Number of Vouchers Impact", "type": "LookupNumber", "range": {"min": 0, "max": 270} }, "raw": 102.85714285714285, "weighted": 102.85714285714285, "error": false } }, "metadata": {}, "errors": [] }, "errors": [] } } ``` | Property | Type | Description | | ---------------------------------------- | ------- | ---------------------------------------------------- | | `ok` | boolean | Success status | | `data` | object | Simulation results | | `data.simulation` | object | Score change information | | `data.simulation.value` | number | Absolute point change in score | | `data.simulation.relativeValue` | number | Relative point change in score | | `data.simulation.impact` | string | Impact type (e.g., “POSITIVE”) | | `data.simulation.adjustedRecipientScore` | number | New simulated score | | `data.calculationResults` | object | Detailed calculation results | | `data.calculationResults.score` | number | Total simulated score | | `data.calculationResults.elements` | object | Detailed breakdown of score elements | | `data.errors` | array | Names of elements that had errors during calculation | **Error Responses** **Code**: 404 Not Found ```json { "ok": false, "error": { "code": "NOT_FOUND", "message": "Failed to calculate subject score" } } ``` ```json { "ok": false, "error": { "code": "NOT_FOUND", "message": "Twitter Profile not found" } } ``` #### Example [Section titled “Example”](#example-1) **Request** ```bash http POST https://api.ethos.network/api/v1/score/simulate \ subjectKey="profileId:1" \ vouchAmount:=1.5 \ numberOfVouchers:=2 ``` **Response** ```json { "ok": true, "data": { "simulation": { "value": 38.70023504412825, "relativeValue": 38.70023504412825, "impact": "POSITIVE", "adjustedRecipientScore": 1749.7002350441282 }, "calculationResults": { "score": 1749.7002350441282, "elements": { "Ethereum Address Age": { "element": { "name": "Ethereum Address Age", "type": "LookupInterval", "ranges": [ {"end": 90, "score": 0}, {"start": 90, "end": 365, "score": 1}, {"start": 365, "end": 1461, "score": 3}, {"start": 1461, "end": 2922, "score": 5}, {"start": 2922, "score": 5} ], "outOfRangeScore": 0 }, "raw": 0, "weighted": 0, "error": false }, "Number of Vouchers Impact": { "element": { "name": "Number of Vouchers Impact", "type": "LookupNumber", "range": {"min": 0, "max": 270} }, "raw": 102.85714285714285, "weighted": 102.85714285714285, "error": false } }, "metadata": {}, "errors": [] }, "errors": [] } } ``` #### Notes [Section titled “Notes”](#notes-1) * You can simulate changes to a user’s score by providing different parameters. * The response includes both the projected score and a detailed breakdown of how each element contributed. * The `impact` field indicates whether the changes would have a positive, negative, or neutral effect. * Only include the parameters you want to simulate; omit others to keep them at their current values. * The simulation doesn’t affect the actual user’s score - it’s only a preview of potential changes. # Signatures > The Signatures API provides endpoints for generating backend signatures required for certain blockchain transactions within the Ethos network. These… ## Overview [Section titled “Overview”](#overview) The Signatures API provides endpoints for generating backend signatures required for certain blockchain transactions within the Ethos network. These signatures authorize actions like creating attestations, registering addresses, or submitting slashes, ensuring that only authenticated and validated operations proceed to the smart contracts. ## Endpoints [Section titled “Endpoints”](#endpoints) ### Create Attestation Signature [Section titled “Create Attestation Signature”](#create-attestation-signature) ```plaintext POST /api/v1/signatures/create-attestation ``` **Description**: Creates a backend-generated signature required for submitting an attestation transaction (e.g., linking a Twitter account) to the blockchain. **Authentication Required**: Yes (Requires Privy Session and Profile) #### Parameters [Section titled “Parameters”](#parameters) **Request Body** ```json { "service": "x.com", // Currently only "x.com" is supported "connectedAddress": "string" // Wallet address connected via Privy } ``` | Property | Type | Required | Description | | ------------------ | ------ | -------- | ------------------------------------------------------------- | | `service` | string | Yes | The service name being attested (currently must be `x.com`). | | `connectedAddress` | string | Yes | The wallet address connected via Privy, matching the session. | #### Responses [Section titled “Responses”](#responses) **Success Response** **Code**: 200 OK ```json { "ok": true, "data": { "randValue": number, // Random nonce value used in the signature "signature": "string", // The backend-generated signature (hex string) "account": "string", // The account ID retrieved from the user's linked Privy account (e.g., Twitter ID) "evidence": "string" // JSON string containing evidence details used in the signature } } ``` | Property | Type | Description | | ---------------- | ------- | ---------------------------------------------------------------------------------------------- | | `ok` | boolean | Indicates if the API call itself was successful. | | `data` | object | Container for the response data. | | `data.randValue` | number | A random nonce value (timestamp) included in the signed message. | | `data.signature` | string | The signature generated by the backend signer over the attestation details. | | `data.account` | string | The account identifier (e.g., Twitter User ID) retrieved from the user’s linked Privy account. | | `data.evidence` | string | A JSON string containing details about the attestation source (Privy OAuth2). | **Error Responses** **Code**: 400 Bad Request ```json { "ok": false, "error": { "code": "VALIDATION_ERROR | BAD_REQUEST", "message": "Invalid service/connectedAddress | Social account already connected" } } ``` **Code**: 401 Unauthorized ```json { "ok": false, "error": { "code": "UNAUTHORIZED", // Middleware handles missing token "message": "Authentication required" } } ``` **Code**: 403 Forbidden ```json { "ok": false, "error": { "code": "FORBIDDEN", "message": "Invalid Privy session | No Twitter account connected" } } ``` #### Example [Section titled “Example”](#example) **Request** ```bash # Needs auth token and connected wallet address CONNECTED_WALLET="0x123...abc" http POST https://api.ethos.network/api/v1/signatures/create-attestation \ Authorization:"Bearer " \ service=x.com \ connectedAddress=$CONNECTED_WALLET ``` **Response** ```json { "ok": true, "data": { "randValue": 1678982400123, "signature": "0x8a7bc52fd7164a3f12b49b6c5f68c6f69de31f515e4d4ec7c055686c8de6331a4b5e09be6e38b9d30b25f3f178c34c7d82778f1c2c6f3dfd0e25e1474a3e83b41c", "account": "1234567890", "evidence": "{\"source\":\"privy\",\"type\":\"OAuth2\",\"id\":\"did:privy:abc123def456\",\"approver\":\"ethos.network\"}" } } ``` #### Notes [Section titled “Notes”](#notes) * Requires authentication. * The user must have linked the specified `service` (Twitter) to their Privy account beforehand. * Checks if the `connectedAddress` matches the authenticated user’s Privy session. * Verifies that an attestation doesn’t already exist for this profile/service/account. * The returned `signature` and `randValue`, along with other details, are used as parameters when calling the `createAttestation` function on the Ethos Attestation smart contract. *** ### Create Slash Signature [Section titled “Create Slash Signature”](#create-slash-signature) ```plaintext POST /api/v1/signatures/create-slash ``` **Description**: Creates a backend-generated signature required for submitting a slash transaction to the blockchain. A slash is a community moderation action that can affect a user’s score or financial status. **Authentication Required**: Yes (Requires Privy Session and Profile) #### Parameters [Section titled “Parameters”](#parameters-1) **Request Body** ```json { "subject": "0x1234...5678", // Can be null if using attestationDetails "amount": 100, "comment": "Reason for slash", "metadata": "{\"description\":\"Additional details about the slash\"}", "attestationDetails": { "service": "x.com", "account": "1234567890" } } ``` | Property | Type | Required | Description | | ---------------------------- | ------ | -------- | -------------------------------------------------------------------------- | | `subject` | string | No\* | Ethereum address of the subject being slashed (null if using attestation). | | `amount` | number | Yes | Positive integer representing the severity/amount of the slash. | | `comment` | string | Yes | Description of why the slash was created (min length 1). | | `metadata` | string | Yes | JSON string with additional metadata about the slash. | | `attestationDetails` | object | Yes | Details about the attestation if slashing by service/account. | | `attestationDetails.service` | string | Yes | Service name (e.g., “x.com”). | | `attestationDetails.account` | string | Yes | Account identifier for the service. | \*Either `subject` (for address-based slashes) or valid `attestationDetails` (for attestation-based slashes) must be provided. #### Responses [Section titled “Responses”](#responses-1) **Success Response** **Code**: 200 OK ```json { "ok": true, "data": { "randValue": 1678982401234, "signature": "0x123456...abcdef" } } ``` | Property | Type | Description | | ---------------- | ------- | --------------------------------------------------------------------- | | `ok` | boolean | Indicates if the API call itself was successful. | | `data` | object | Container for the response data. | | `data.randValue` | number | A random nonce value (timestamp) included in the signed message. | | `data.signature` | string | The signature generated by the backend signer over the slash details. | **Error Responses** **Code**: 400 Bad Request ```json { "ok": false, "error": { "code": "VALIDATION_ERROR", "message": "Invalid input parameters" } } ``` **Code**: 401 Unauthorized ```json { "ok": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` **Code**: 403 Forbidden ```json { "ok": false, "error": { "code": "FORBIDDEN", "message": "Invalid Privy session | User cannot slash", "details": { "code": "FORBIDDEN_SLASH" } } } ``` #### Example [Section titled “Example”](#example-1) **Request** ```bash # Needs auth token http POST https://api.ethos.network/api/v1/signatures/create-slash \ Authorization:"Bearer " \ subject=null \ amount:=100 \ comment="Impersonating other users" \ metadata="{\"description\":\"Created fake account mimicking project founder\"}" \ attestationDetails:='{"service":"x.com","account":"1234567890"}' ``` **Response** ```json { "ok": true, "data": { "randValue": 1678982401234, "signature": "0x4d8fb7c124fecb927e35b7dc913b2716f5ce9c7bb6075cbde0bd41677c095c6b5cdcce7f2605a6161a86202feea8a9b6aa051b0d9c995a79a42e71551dc23cf31b" } } ``` #### Notes [Section titled “Notes”](#notes-1) * Requires authentication. * The user must have permission to create slashes (authorization checked by the `canSlash` function). * The returned `signature` and `randValue` are used as parameters when calling the `createSlash` function on the Ethos Slash smart contract. * For address-based slashes, provide the `subject` parameter with an Ethereum address. * For attestation-based slashes (e.g., Twitter accounts), set `subject` to null and provide valid `attestationDetails`. * The signature combines the authenticated user’s profile ID, a random value, and all slash parameters. *** # Slashes > The Slashes API provides endpoints for interacting with slash events, which are community moderation actions within the Ethos network. It allows retrieving… ## Overview [Section titled “Overview”](#overview) The Slashes API provides endpoints for interacting with slash events, which are community moderation actions within the Ethos network. It allows retrieving slash details, checking potential slash validity, and determining user roles in relation to a specific slash. ## Endpoints [Section titled “Endpoints”](#endpoints) ### List Slashes [Section titled “List Slashes”](#list-slashes) ```plaintext GET /api/v1/slashes ``` **Description**: Retrieves a list of slashes (community moderation actions), optionally filtered by author, subject, and status. **Authentication Required**: No #### Parameters [Section titled “Parameters”](#parameters) **Query Parameters** ```typescript { author?: string; // Optional: Filter by author's userkey (e.g., eth:0x..., did:privy:...) subject?: string; // Optional: Filter by subject's userkey status?: 'open' | 'closed'; // Optional: Filter by slash status (defaults to all) limit?: number; // Optional: Pagination limit (default: 50, max: 100) offset?: number; // Optional: Pagination offset (default: 0) } ``` | Parameter | Type | Required | Default | Description | | --------- | ---------------------- | -------- | ------- | ---------------------------------------------------- | | `author` | string (Userkey) | No | - | Filter slashes created by this author. | | `subject` | string (Userkey) | No | - | Filter slashes targeting this subject. | | `status` | `'open'` \| `'closed'` | No | all | Filter slashes by their status (`open` or `closed`). | | `limit` | number | No | 50 | Maximum number of slashes to return. Max 100. | | `offset` | number | No | 0 | Number of slashes to skip for pagination. | #### Responses [Section titled “Responses”](#responses) **Success Response** **Code**: 200 OK ```json { "ok": true, "data": { "values": [ { "id": number, // Slash ID (from contract event) "authorProfileId": number, // Author's profile ID "subject": "string | null", // Subject's address if applicable, otherwise null "attestationDetails": { // Subject's attestation details if applicable, otherwise null "service": "string", "account": "string" } | null, "slashType": "SCORE" | "FINANCIAL", // Note: Enum value casing confirmed "amount": number, // Amount slashed (Number) "duration": number, // Duration in seconds "comment": string, "metadata": string, // Additional metadata (often JSON string) "createdAt": number, // Unix timestamp (seconds) "closedAt": number, // Unix timestamp (seconds) when slash closed (expiration or cancellation) "cancelledAt": number // Unix timestamp (seconds) if cancelled, otherwise 0 // "expiresAt": number | null // Unix timestamp (seconds) - Likely only present for open slashes } ], "total": number, // Total number of slashes matching the query "limit": number, // The limit used for this response "offset": number // The offset used for this response } } ``` *Note: The exact structure of the `subject` object and other fields within the `values` array depends on the `convert.toSlash` function and needs confirmation via testing.* **Error Responses** **Code**: 400 Bad Request ```json { "ok": false, "error": { "code": "VALIDATION_ERROR", "message": "Invalid input parameters", // Example message "details": { /* Zod error details */ } } } ``` #### Example [Section titled “Example”](#example) **Request** ```bash # Get the 5 most recent open slashes http GET https://api.ethos.network/api/v1/slashes status==open limit==5 # Get slashes authored by a specific profile (using DID) http GET https://api.ethos.network/api/v1/slashes author=="did:privy:user123" ``` **Response** ```json # Example Response (Structure Confirmed, Values Illustrative) { "ok": true, "data": { "values": [ { "id": 28, "authorProfileId": 1017, "subject": null, "attestationDetails": { "service": "x.com", "account": "1142606887" }, "slashType": "SCORE", "amount": 210, "duration": 172800, "comment": "Ran one of the biggest and most unreported FRAUDS ever in Crypto", "metadata": "{\"description\":\"Somehow he is still walking free...\"}", "createdAt": 1743130149, "closedAt": 1743302949, "cancelledAt": 0 } // ... more slashes up to limit ], "total": 50, // Example total "limit": 50, "offset": 0 } } ``` #### Notes [Section titled “Notes”](#notes) * Returns slashes ordered by creation date descending. * Uses standard pagination (`limit`, `offset`). * Supports filtering by author, subject (using userkey format), and status. ### Get Slash Roles [Section titled “Get Slash Roles”](#get-slash-roles) ```plaintext GET /api/v1/slashes/:id/roles ``` **Description**: Retrieves the roles of specified profiles related to a specific slash (e.g., slasher, defender, voter). **Authentication Required**: No (Assumed, needs verification) #### Parameters [Section titled “Parameters”](#parameters-1) **Path Parameters** | Parameter | Type | Description | | --------- | ------ | -------------------- | | `id` | number | The ID of the slash. | **Query Parameters** ```typescript { profileId: number | number[]; // Profile ID(s) to check roles for } ``` | Parameter | Type | Required | Description | | ----------- | ------ | --------- | ----------- | | `profileId` | number | number\[] | Yes | #### Responses [Section titled “Responses”](#responses-1) **Success Response** **Code**: 200 OK ```json { "ok": true, "data": { "": "slasher" | "defender" | "voted_slash" | "voted_defend" // ... more profileId: role pairs } } ``` | Role | Description | | -------------- | ----------------------------------------------------- | | `slasher` | The profile authored the slash. | | `defender` | The profile is the subject of the slash. | | `voted_slash` | The profile upvoted the slash (supported slasher). | | `voted_defend` | The profile downvoted the slash (supported defender). | **Error Responses** **Code**: 400 Bad Request (Example: Missing profileId) ```json { "ok": false, "error": { "code": "VALIDATION_ERROR", "message": "Invalid input: profileId is required" } } ``` **Code**: 404 Not Found (Example: Slash ID not found) ```json { "ok": false, "error": { "code": "NOT_FOUND", "message": "Slash not found" } } ``` #### Example [Section titled “Example”](#example-1) **Request** ```bash # Get roles for profile 123 and 456 regarding slash 28 http GET https://api.ethos.network/api/v1/slashes/28/roles profileId==123 profileId==456 ``` **Response** ```json { "ok": true, "data": {} } ``` #### Notes [Section titled “Notes”](#notes-1) * Used to determine relationship of specific users to a slash. * Requires the numerical slash ID and at least one profile ID. # Users > The Users API returns statistics about a user in the Ethos network, including reviews, slashes and vouches. ## Overview [Section titled “Overview”](#overview) The Users API returns statistics about a user in the Ethos network, including reviews, slashes and vouches. ## Endpoints [Section titled “Endpoints”](#endpoints) ### Get User Statistics [Section titled “Get User Statistics”](#get-user-statistics) ```plaintext GET /api/v1/users/:userkey/stats ``` **Description**: Retrieves comprehensive statistics about a user, including review and vouch information. **Authentication Required**: No #### Parameters [Section titled “Parameters”](#parameters) **Path Parameters** | Name | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------- | | `userkey` | string | Yes | The userkey for the user. Can be in the format of “profileId:123”, “address:0x1234…”, or “service:x.com:username:username” | **Query Parameters** | Name | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------------------------- | | `startDate` | string | No | Filter statistics to data after this date (ISO format) | | `endDate` | string | No | Filter statistics to data before this date (ISO format) | #### Responses [Section titled “Responses”](#responses) **Success Response** **Code**: 200 OK ```json { "ok": true, "data": { "profileId": 123, "market": null, "reviews": { "received": 10, "positiveReviewPercentage": 90, "positiveReviewCount": 9, "negativeReviewCount": 1, "neutralReviewCount": 0 }, "slashes": { "count": 0, "openSlash": null }, "vouchTotals": [ { "token": { "id": "eth", "address": null, "decimals": 18 }, "count": { "given": 2, "received": 3 }, "balance": { "given": "2000000000000000000n", "received": "5000000000000000000n" } } ], "influenceFactor": 12, "influenceFactorPercentile": 40 } } ``` | Property | Type | Description | | --------------------------------------- | -------------- | -------------------------------------------------------------------------------------- | | `ok` | boolean | Success status | | `data` | object | User statistics data | | `data.profileId` | number \| null | Ethos profile ID, or null when the userkey has no profile | | `data.market` | object \| null | The user’s reputation market, or null when there is none | | `data.reviews` | object | Review statistics | | `data.reviews.received` | number | Total number of reviews received | | `data.reviews.positiveReviewPercentage` | number | Percentage of positive reviews (excluding neutral reviews) | | `data.reviews.positiveReviewCount` | number | Number of positive reviews | | `data.reviews.negativeReviewCount` | number | Number of negative reviews | | `data.reviews.neutralReviewCount` | number | Number of neutral reviews | | `data.slashes` | object | Slash statistics | | `data.slashes.count` | number | Number of slashes against the user | | `data.slashes.openSlash` | object \| null | The slash currently open against the user, or null | | `data.vouchTotals` | array | Lifetime vouch totals, one entry per token. Empty when a date filter is set | | `data.vouchTotals[].token` | object | The vouch token: `id` (`eth` or `whuf`), contract `address` (null for ETH), `decimals` | | `data.vouchTotals[].count.given` | number | Number of vouches the user has given in this token | | `data.vouchTotals[].count.received` | number | Number of vouches the user has received in this token | | `data.vouchTotals[].balance.given` | string | Amount the user has vouched, in the token’s smallest unit, as digits followed by `n` | | `data.vouchTotals[].balance.received` | string | Amount vouched for the user, in the same format | | `data.influenceFactor` | number \| null | The user’s influence factor | | `data.influenceFactorPercentile` | number \| null | Percentile of the influence factor compared to all users (0-100) | #### Example [Section titled “Example”](#example) **Request** ```bash http GET https://api.ethos.network/api/v1/users/profileId:123/stats ``` **Request with Date Filters** ```bash http GET https://api.ethos.network/api/v1/users/profileId:123/stats \ startDate=2023-01-01 \ endDate=2023-12-31 ``` #### Notes [Section titled “Notes”](#notes) * If a user has multiple userkeys (e.g., multiple addresses or social accounts), the statistics are aggregated across all of them. * For reviews, the positive review percentage excludes neutral reviews from the calculation. * `vouchTotals` covers the user’s whole history. A request with `startDate` or `endDate` returns it empty. # Vouches > The Vouches API allows you to query and analyze vouches in the Ethos network. Vouches represent a stake of Ethereum that one user places on another,… ## Overview [Section titled “Overview”](#overview) The Vouches API allows you to query and analyze vouches in the Ethos network. Vouches represent a stake of Ethereum that one user places on another, indicating trust and confidence in that user. The API provides endpoints for querying vouches and their rewards. ## Endpoints [Section titled “Endpoints”](#endpoints) ### Query Vouches [Section titled “Query Vouches”](#query-vouches) ```plaintext POST /api/v1/vouches ``` **Description**: Retrieves vouches based on various filters such as IDs, author profile IDs, subject profile IDs, and more. **Authentication Required**: No #### Parameters [Section titled “Parameters”](#parameters) **Request Body** ```json { "ids": [1, 2, 3], "authorProfileIds": [123, 456], "subjectProfileIds": [789, 101], "subjectAddresses": ["0x1234...", "0x5678..."], "subjectAttestationHashes": ["0xabcd...", "0xef01..."], "archived": false, "duration": "90d", "orderBy": { "vouchedAt": "desc" }, "limit": 10, "offset": 0 } ``` | Property | Type | Required | Description | | --------------------------------------------------------------- | ---------------- | -------- | ----------------------------------------------------------------- | | `ids` | array of numbers | No | Array of vouch IDs | | `authorProfileIds` | array of numbers | No | Array of profile IDs of vouch authors | | `subjectProfileIds` | array of numbers | No | Array of profile IDs of vouch subjects | | `subjectAddresses` | array of strings | No | Array of Ethereum addresses of vouch subjects | | `subjectAttestationHashes` | array of strings | No | Array of attestation hashes of vouch subjects | | `archived` | boolean | No | Whether to include archived vouches | | `duration` | string | No | Return vouches after this duration (e.g., “90d” for last 90 days) | | `orderBy` | object | No | Sorting options | | `orderBy.balance` or `orderBy.vouchedAt` or `orderBy.updatedAt` | string | No | Sort by field: “asc” or “desc” | | `limit` | number | No | Number of results to return (default: 10, maximum 100) | | `offset` | number | No | Offset for pagination (default: 0) | #### Responses [Section titled “Responses”](#responses) **Success Response** **Code**: 200 OK ```json { "ok": true, "data": { "values": [ { "id": 1, "authorProfileId": 123, "subjectProfileId": 789, "subjectAddress": "0x1234567890123456789012345678901234567890", "attestationHash": null, "staked": "2000000000000000000", // 2 ETH in wei "balance": "2000000000000000000", "vouchedAt": 1735689600, "updatedAt": 1735689600, "archivedAt": null, "archived": false, "mutualId": 2, "events": [ { "id": 123, "txHash": "0x1234567890123456789012345678901234567890123456789012345678901234", "blockNumber": 12345678, "createdAt": 1735689500, "updatedAt": 1735689500 } ], "attestationDetails": null } ], "limit": 10, "offset": 0, "total": 1 } } ``` | Property | Type | Description | | ---------------------------------- | ------- | ------------------------------------------------------------- | | `ok` | boolean | Success status | | `data` | object | Response data container | | `data.values` | array | Array of vouch objects | | `data.values[].id` | number | Vouch ID | | `data.values[].authorProfileId` | number | Profile ID of the author | | `data.values[].subjectProfileId` | number | Profile ID of the subject (if applicable) | | `data.values[].subjectAddress` | string | Ethereum address of the subject (if applicable) | | `data.values[].attestationHash` | string | Attestation hash of the subject (if applicable) | | `data.values[].staked` | string | Amount of ETH staked in wei | | `data.values[].balance` | string | Current balance of the vouch in wei | | `data.values[].vouchedAt` | number | Unix timestamp of when the vouch was created | | `data.values[].updatedAt` | number | Unix timestamp of when the vouch was last updated | | `data.values[].archivedAt` | number | Unix timestamp of when the vouch was archived (if applicable) | | `data.values[].archived` | boolean | Whether the vouch is archived | | `data.values[].mutualId` | number | ID of the mutual vouch (if applicable) | | `data.values[].events` | array | Blockchain events associated with the vouch | | `data.values[].attestationDetails` | object | Details about the attestation (if applicable) | | `data.limit` | number | Number of results returned | | `data.offset` | number | Current pagination offset | | `data.total` | number | Total number of results matching the query | #### Example [Section titled “Example”](#example) **Request** ```bash http POST https://api.ethos.network/api/v1/vouches \ subjectProfileIds:='[789]' \ limit:=10 \ offset:=0 ``` #### Notes [Section titled “Notes”](#notes) * By default, results are sorted by vouch date in descending order (newest first). * The API enforces a maximum of 100 vouches that can be requested at once. * If a vouch references an attestation hash that corresponds to a Twitter account, the `attestationDetails` field will be populated. *** ### Get Vouch Rewards [Section titled “Get Vouch Rewards”](#get-vouch-rewards) ```plaintext POST /api/v1/vouches/rewards ``` **Description**: Calculates the rewards earned from vouches for a specific target. **Authentication Required**: No #### Parameters [Section titled “Parameters”](#parameters-1) **Request Body** ```json { "target": "profileId:123" } ``` | Property | Type | Required | Description | | -------- | ------ | -------- | ---------------------------------------------- | | `target` | string | Yes | Userkey of the target to calculate rewards for | #### Responses [Section titled “Responses”](#responses-1) **Success Response** **Code**: 200 OK ```json { "ok": true, "data": { "earned": 0.05, "potentialEarnings": 0.08, "totalStaked": 5.0 } } ``` | Property | Type | Description | | ------------------------ | ------- | ------------------------------------------ | | `ok` | boolean | Success status | | `data` | object | Vouch rewards data | | `data.earned` | number | Total ETH earned from vouches | | `data.potentialEarnings` | number | Potential additional earnings from vouches | | `data.totalStaked` | number | Total ETH staked in vouches | #### Example [Section titled “Example”](#example-1) **Request** ```bash http POST https://api.ethos.network/api/v1/vouches/rewards \ target="profileId:123" ``` #### Notes [Section titled “Notes”](#notes-1) * Rewards are earned based on the protocol’s reward distribution mechanism. * Potential earnings represent the additional rewards that could be earned in the future from existing vouches. # API explorer > Browse and call every Ethos API v2 endpoint from the browser. The explorer needs JavaScript. The same endpoints are documented under API v2 in the sidebar. # Changelog > These endpoints will be removed after the advertised date. We will do our best to notify consumers (by their advertised X-Ethos-Client header) in advance of… ## Recent Changes [Section titled “Recent Changes”](#recent-changes) * 9 Nov 2026 – Removed deprecated vouch fields. `stats.vouchTotals` (one entry per token) and `topVouch.amountWei` carry the same data in the same responses: * `stats.vouch` on user objects * `vouches` on `GET /api/v1/users/:userkey/stats`; requests with `startDate` or `endDate` no longer return vouch statistics * `vouchToken` and every `topVouch` field except `amountWei` on user stats * `stats.vouches` on trending users * 6 Nov 2026 – Removed the XP v1 endpoints: * `POST /api/v1/xp/extension-daily-checkin` * `GET /api/v1/users/xp-leaderboard` * `GET /api/v1/users/xp-leaderboard/export` * 3 Nov 2026 – Removed XP spending endpoints and an unused activity endpoint: * `POST /api/v2/contributions/forgive-self` * `POST /api/v2/xp/decision` * `POST /api/v2/activities/profile/saved-posts` * 29 Oct 2026 – Removed project listings (project sentiment): * `GET /api/v2/projects` * `GET /api/v2/projects/suggested` * `GET /api/v2/projects/confirm` * `GET /api/v2/projects/username/{username}` * `GET /api/v2/projects/votes/balance` * `GET /api/v2/projects/votes/bulk-totals` * `GET /api/v2/projects/{projectId}` * `PUT /api/v2/projects/{projectId}` * `GET /api/v2/projects/{projectId}/details` * `GET /api/v2/projects/{projectId}/chart` * `GET /api/v2/projects/{projectId}/voters` * `POST /api/v2/projects/{projectId}/votes` * `GET /api/v2/projects/{projectId}/team` * `POST /api/v2/projects/{projectId}/team` * `DELETE /api/v2/projects/{projectId}/team` * `POST /api/v2/projects/{projectId}/chains` * `DELETE /api/v2/projects/{projectId}/chains/{chainId}` * `GET /api/v2/internal/listings` * `GET /api/v2/internal/listings/{username}` * 23 Oct 2026 – Removed deprecated markets v1 endpoints: * `GET /api/v1/markets/search` * `GET /api/v1/markets/:profileId` * `GET /api/v2/markets/configs` * `GET /api/v2/markets/fees` * `GET /api/v2/markets/holdings` * `GET /api/v2/markets/stats` * `GET /api/v2/markets/{profileId}/change` * `GET /api/v2/markets/{profileId}/vote-price` * `POST /api/v2/wallets/privy/markets/buy` * 19 Oct 2026 – Removed deprecated markets v1 endpoints: * `GET /api/v1/markets/activity/:address` * `GET /api/v1/markets/holdings/:address/total` * `GET /api/v1/markets/leaderboard/profit` * `GET /api/v1/markets/leaderboard/xp` * `GET /api/v1/markets/tx/history` * `GET /api/v1/markets/volume/:address` * `GET /api/v2/markets/featured` * `GET /api/v2/markets/simulate-buy` * `GET /api/v2/markets/users/by/x/{username}` * `POST /api/v2/markets/users/by/addresses` * `GET /api/v2/xp/user/{userkey}/leaderboard-rank` * 30 Sep 2026 – Removed deprecated activity endpoints: * `GET /api/v1/activities/actor/:userkey` * `POST /api/v1/activities/actors` * `GET /api/v1/activities/invite/accepted-by/:profileId` * 27 Mar 2026 – Added API key support for programmatic access: * Create, list, and revoke API keys via SIWE signature (`/api/v2/api-keys`) * Authenticate any profile-scoped endpoint with the `X-Ethos-Api-Key` header * 1 Dec 2025 – Removed deprecated endpoints: * `POST /api/v1/invitations` * `GET /api/v1/invitations/pending/:address`, * `GET /api/v1/profiles/directory` * 6 Oct 2025 – Removed deprecated endpoints: * `POST /api/v1/reviews` * `POST /api/v1/profiles/recent` * 9 Sep 2025 – Removed deprecated endpoints: * `POST /api/v1/reply` * `POST /api/v1/reviews/count` * 8 Aug 2025 – Removed deprecated `/api/v1/activities` endpoint *** ## Deprecated Endpoints [Section titled “Deprecated Endpoints”](#deprecated-endpoints) These endpoints will be removed after the advertised date. We will do our best to notify consumers (by their advertised `X-Ethos-Client` header) in advance of removal. | Endpoint | Description | Sunset | | -------- | ----------- | ------ | | | | | *** ## Beta Endpoints [Section titled “Beta Endpoints”](#beta-endpoints) Beta endpoints are recent additions and are still subject to rapid change without further notification to consumers. We will remove the ‘beta’ tag once they are stable. *** ## Internal Endpoints [Section titled “Internal Endpoints”](#internal-endpoints) Internal endpoints are used by Ethos frontend and are not intended for public consumption. They may change without notice. We intend to ‘publish’ them to beta status. | Method | Path | Description | | ------ | --------------------------- | ------------------------------ | | `GET` | `/internal/users/{userkey}` | Fetch user details by userkey. | # Ethos Everywhere Wallet Integration > Ethos Everywhere Wallet is a managed wallet solution that brings Ethos functionality into partner applications. Users can post reviews, vote, and reply on… ### Overview [Section titled “Overview”](#overview) Ethos Everywhere Wallet is a managed wallet solution that brings Ethos functionality into partner applications. Users can post reviews, vote, and reply on Ethos directly from those apps, without wallet popups or manual transaction signing. This creates a seamless user experience while maintaining full security through server-side managed wallets powered by Privy. #### What is Ethos Everywhere Wallet? [Section titled “What is Ethos Everywhere Wallet?”](#what-is-ethos-everywhere-wallet) Ethos Everywhere Wallet allows users to interact with the Ethos Network from any partner application without needing to: * Install a crypto wallet * Manually sign transactions * Pay gas fees (for qualified users) * Switch from the partner app to Ethos and back Once a user is authenticated on Ethos and has enabled Ethos Everywhere Wallet in their settings, they can immediately start posting reviews, voting on content, and engaging with the Ethos community from partner applications - all with a single click. #### Use Cases [Section titled “Use Cases”](#use-cases) Partner applications can integrate Ethos Everywhere Wallet to enable users to: * **Post Reviews**: Submit credibility reviews for Ethereum addresses, Twitter accounts, or other supported subjects * **Vote on Activities**: Upvote or downvote reviews, vouches, attestations, slashes, broker posts, projects, reputation markets, and replies * **Vote on Slashes**: Support or oppose community moderation actions for alleged unethical behavior * **Reply to Content**: Post comments and engage in discussions on any activity type #### Benefits [Section titled “Benefits”](#benefits) **For Users:** * No wallet installation required * No transaction signing popups * No gas fees for users with sufficient credibility score * Seamless single-click interactions * Unified Ethos identity across all partner applications **For Partners:** * Lower friction for user onboarding * Higher engagement rates * Access to Ethos credibility data * Enhanced user experience * Built-in spam protection through credibility requirements ### Becoming an Allowlisted Partner [Section titled “Becoming an Allowlisted Partner”](#becoming-an-allowlisted-partner) To integrate Ethos Everywhere Wallet into your application, you must be added to the Ethos partner allowlist. This process ensures the security and integrity of the Ethos Network. #### Requirements [Section titled “Requirements”](#requirements) To become an allowlisted partner, your application must meet the following requirements: 1. **Domain Verification**: You must own and control the domain from which API requests will be made 2. **Security Review**: Your application will undergo a security review to ensure it follows best practices 3. **Clear Use Case**: Provide a clear description of how you plan to use Ethos Everywhere Wallet 4. **User Experience**: Demonstrate that your integration provides value to Ethos users 5. **Client Identification**: Implement the `X-Ethos-Client` header with your application name/version #### Application Process [Section titled “Application Process”](#application-process) 1. **Contact the Ethos Team**: Reach out through one of these channels: * Email: * Discord: Join the [Ethos Discord](https://discord.gg/trust-ethos) * Twitter: [@ethos_network](https://x.com/ethos_network) 2. **Provide Application Details**: * Application name and description * Domain(s) that will make API requests * Expected use cases and integration plans * Technical contact information 3. **Security Review**: The Ethos team will review your application and may request additional information or security measures 4. **Allowlist Configuration**: Once approved, the Ethos team will: * Add your domain to the CORS allowlist (`isAllowedOrigin()`) * Configure your client to show in up the “this review left from” display #### API Endpoints [Section titled “API Endpoints”](#api-endpoints) All Ethos Everywhere Wallet endpoints are available under the `wallets` tag in the [API v2 reference](https://api.ethos.network/docs/openapi.json). **Authentication** **GET /wallets/privy/auth-check** Verify that the user is authenticated and has access to Ethos Everywhere Wallet. * Returns: `{ ok: boolean, profileId?: number }` * Use this to check if the user can perform wallet actions * Automatically refreshes expired access tokens **Review Creation** **POST /wallets/privy/post/review** Create a review using the Ethos Everywhere Wallet. Requires review subject, score, title, and optional content. **POST /wallets/privy/post/review/by-address** Create a review for a specific Ethereum address. **POST /wallets/privy/post/review/by-x** Create a review for a Twitter (x.com) account by ID or username. All review endpoints return: * `hash`: Transaction hash * `review`: Review data (if available within timeout) * `reviewSlug`: Slug for the review URL **Voting** **POST /wallets/activity/{activityType}/{id}/vote** Submit an upvote or downvote on any activity type: * `review`, `vouch`, `attestation`, `slash`, `broker-post`, `project`, `reputation-market`, `reply` Parameters: * `activityType`: The type of activity to vote on * `id`: The activity ID * `isUpvote`: `true` for upvote, `false` for downvote **Replies** **POST /wallets/activity/{activityType}/{id}/reply** Post a reply to any activity type: * `review`, `vouch`, `attestation`, `slash`, `broker-post`, `project`, `reputation-market`, `reply` Parameters: * `activityType`: The type of activity to reply to * `id`: The activity ID * `content`: Reply text content * `metadata`: Optional metadata object #### Integration Examples [Section titled “Integration Examples”](#integration-examples) **Authentication Check** ```typescript async function checkWalletAuth() { try { const response = await fetch('https://api.ethos.network/api/v2/wallets/privy/auth-check', { method: 'GET', headers: { 'X-Ethos-Client': 'my-app@1.0.0', }, credentials: 'include', // Important: include cookies }); const data = await response.json(); if (data.ok) { console.log('User is authenticated with profile ID:', data.profileId); return true; } return false; } catch (error) { console.error('Auth check failed:', error); return false; } } ``` **Posting a Review** ```typescript async function postReview(address: string, score: 'positive' | 'neutral' | 'negative', title: string, content?: string) { try { const response = await fetch('https://api.ethos.network/api/v2/wallets/privy/post/review/by-address', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Ethos-Client': 'my-app@1.0.0', }, credentials: 'include', // Important: include cookies body: JSON.stringify({ address, score, title, content, waitForReviewTimeoutSeconds: 5, // Wait up to 5 seconds for review data }), }); if (!response.ok) { const error = await response.json(); throw new Error(error.message || 'Failed to post review'); } const data = await response.json(); console.log('Review posted with hash:', data.hash); if (data.review) { console.log('Review ID:', data.review.id); console.log('Review URL:', `https://ethos.network/review/${data.reviewSlug}`); } return data; } catch (error) { console.error('Failed to post review:', error); throw error; } } ``` **Voting on an Activity** ```typescript async function voteOnReview(reviewId: number, isUpvote: boolean) { try { const response = await fetch(`https://api.ethos.network/api/v2/wallets/activity/review/${reviewId}/vote`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Ethos-Client': 'my-app@1.0.0', }, credentials: 'include', body: JSON.stringify({ activityType: 'review', id: reviewId, isUpvote, }), }); if (!response.ok) { const error = await response.json(); throw new Error(error.message || 'Failed to vote'); } const data = await response.json(); console.log('Vote submitted with hash:', data.hash); return data; } catch (error) { console.error('Failed to vote:', error); throw error; } } ``` #### Error Handling [Section titled “Error Handling”](#error-handling) Ethos Everywhere Wallet endpoints may return various error codes: | Error Code | HTTP Status | Description | | --------------------------- | ----------- | ------------------------------------ | | `UNAUTHENTICATED` | 401 | User is not authenticated | | `WALLET_NOT_FOUND` | 404 | User does not have a wallet | | `EMBEDDED_WALLET_NOT_FOUND` | 404 | Embedded wallet not found for user | | `INSUFFICIENT_FUNDS` | 400 | Not enough funds for transaction | | `NONCE_CONFLICT` | 409 | Nonce collision; retry the request | | `CONTRACT_REVERT` | 400 | Transaction reverted on-chain | | `RATE_LIMITED` | 429 | Too many requests | | `BLOCKCHAIN_UNAVAILABLE` | 503 | Network is unavailable | | `ENDPOINT_DISABLED` | 404 | Feature is not enabled for this user | **Error Handling Pattern:** ```typescript async function handleWalletRequest(requestFn: () => Promise) { try { const response = await requestFn(); if (!response.ok) { const error = await response.json(); switch (error.code) { case 'UNAUTHENTICATED': // Redirect to login or show authentication prompt redirectToLogin(); break; case 'INSUFFICIENT_FUNDS': // Show message that user needs to add funds showError('Insufficient funds. Please add ETH to your wallet.'); break; case 'NONCE_CONFLICT': // Retry the request once console.log('Nonce conflict, retrying...'); return await requestFn(); case 'RATE_LIMITED': // Back off and retry later showError('Too many requests. Please try again in a moment.'); break; case 'ENDPOINT_DISABLED': // Feature not available for this user showError('This feature is not available for your account.'); break; default: // Generic error handling showError(error.message || 'An error occurred'); } return null; } return await response.json(); } catch (error) { console.error('Request failed:', error); showError('Network error. Please check your connection.'); return null; } } ``` ### Best Practices [Section titled “Best Practices”](#best-practices) 1. **Always Include Credentials**: Set `credentials: 'include'` in fetch requests to send cookies 2. **Set X-Ethos-Client Header**: Include your app identifier in every request 3. **Check Authentication First**: Use `/auth-check` before attempting wallet operations 4. **Handle Errors Gracefully**: Implement proper error handling for all error codes 5. **Respect Rate Limits**: Implement exponential backoff for rate limit errors 6. **Use Appropriate Timeouts**: Set reasonable `waitForReviewTimeoutSeconds` values (5-10 seconds) 7. **Monitor Transaction Status**: Use the returned transaction hash to verify on-chain status if needed 8. **Cache Authentication State**: Avoid redundant auth checks by caching the authentication state 9. **Provide User Feedback**: Show loading states and success/error messages for all operations ### Support [Section titled “Support”](#support) If you encounter issues or have questions: * **Documentation**: * **API Reference**: * **Email**: * **Discord**: Join the [Ethos Discord](https://discord.gg/trust-ethos) * **Status Page**: Check [status.ethos.network](https://status.ethos.network) for service status # Log in with Ethos > Use Log in with Ethos to authenticate users into your application using their Ethos Everywhere wallet. This integration is powered by [Privy](https://www.privy.io/), allowing users to sign in with the Ethos Everywhere wallet. You can find a working reference implementation here: * Example app: [https://login-example.ethos.network](https://login-example.ethos.network/) * Source code: ### 1. Prerequisites [Section titled “1. Prerequisites”](#1-prerequisites) To integrate Log in with Ethos, you need: * A Privy account * An application configured in the [Privy Developer Dashboard](https://dashboard.privy.io/account) * An Ethos account (for testing login) *** ### 2. Configure Privy [Section titled “2. Configure Privy”](#2-configure-privy) #### Step 1 — Create a Privy app [Section titled “Step 1 — Create a Privy app”](#step-1--create-a-privy-app) 1. Go to Privy Developer Dashboard 2. [Create a new application (or use an existing one)](https://docs.privy.io/basics/get-started/dashboard/create-new-app) 3. Copy your APP ID You will use this on the client side when initializing Privy. #### Step 2 — Enable integration with Ethos [Section titled “Step 2 — Enable integration with Ethos”](#step-2--enable-integration-with-ethos) Inside your Privy dashboard: 1. Navigate to Global wallet → Integrations 2. Find **Ethos Network** and enable it. ### 3. Install Privy in your app [Section titled “3. Install Privy in your app”](#3-install-privy-in-your-app) [Add Privy’s SDK to your project](https://docs.privy.io/basics/react/installation). *** ### 4. Initialize Privy [Section titled “4. Initialize Privy”](#4-initialize-privy) Use your Privy App ID to initialize Privy in your React app: ```jsx import { PrivyProvider } from '@privy-io/react-auth'; ``` *** ### 5. Trigger Login with Ethos [Section titled “5. Trigger Login with Ethos”](#5-trigger-login-with-ethos) Inside your app: ```jsx import { usePrivy } from '@privy-io/react-auth'; const { login } = usePrivy(); ``` ![]() ### Example app [Section titled “Example app”](#example-app) A fully working implementation demonstrating the entire flow: * Live Demo: [https://login-example.ethos.network](https://login-example.ethos.network/) * GitHub Repo: # MCP server > Install the Ethos reputation lookups as MCP tools in Claude, Cursor, Claude Code or any MCP client. Free, read-only, no key. Ethos serves its most useful reputation lookups as an [MCP](https://modelcontextprotocol.io) server, so an agent that installs tools gets them without reading the API reference or paying over x402: ```plaintext https://developers.ethos.network/mcp ``` Streamable HTTP, no authentication, read-only. Five tools, one per lookup, each answering with the same JSON the free API returns. | Tool | Takes | Returns | Same as | | ----------------------- | ----------------------------------- | ----------------------------------------------------------- | --------------------------------------------- | | `ethos_score` | `userkey` | Credibility score (0 to 2800) and level | `GET /api/v2/score/userkey` | | `ethos_user_by_x` | `handle` (X handle or account id) | The Ethos profile behind an X account, every linked account | `GET /api/v2/user/by/x/{accountIdOrUsername}` | | `ethos_user_by_address` | `address` (EVM, `0x…`) | The Ethos profile holding a wallet | `GET /api/v2/user/by/address/{address}` | | `ethos_search_users` | `query`, optional `limit`, `offset` | Profiles matching a name, handle or address fragment | `GET /api/v2/users/search` | | `ethos_xp` | `userkey` | Total XP across all seasons | `GET /api/v2/xp/user/{userkey}` | A `userkey` names a person any way Ethos knows them: `address:0x…`, `profileId:1`, `service:x.com:username:ethos_network`, `service:x.com:`, `service:discord:` or `service:telegram:`. The server’s `initialize` answer carries instructions on which tool to reach for and how to read a score (below 800 untrusted, 800 to 1199 questionable, 1200 to 1399 neutral, 1400 and up increasingly reputable). Scores reflect peer judgement and can be gamed at the margins: a strong signal, not a verdict. ## Connect a client [Section titled “Connect a client”](#connect-a-client) * Claude Code ```sh claude mcp add --transport http ethos https://developers.ethos.network/mcp ``` * Cursor In `.cursor/mcp.json` (per project) or `~/.cursor/mcp.json` (everywhere): ```json { "mcpServers": { "ethos": { "url": "https://developers.ethos.network/mcp" } } } ``` * Claude Desktop and claude.ai Settings → Connectors → **Add custom connector**: name `Ethos`, URL `https://developers.ethos.network/mcp`, no OAuth. For a Claude Desktop that only takes local servers, `claude_desktop_config.json` can bridge to it: ```json { "mcpServers": { "ethos": { "command": "npx", "args": ["-y", "mcp-remote", "https://developers.ethos.network/mcp"] } } } ``` * curl The endpoint is plain JSON-RPC over POST, so a shell can list and call the tools: ```sh curl -s https://developers.ethos.network/mcp \ -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' curl -s https://developers.ethos.network/mcp \ -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"ethos_score","arguments":{"userkey":"service:x.com:username:ethos_network"}}}' # {"result":{"content":[{"type":"text","text":"{\"score\":2441,\"level\":\"revered\"}"}]},"jsonrpc":"2.0","id":2} ``` Any client that speaks MCP’s streamable HTTP transport works the same way; a `GET` on the URL from a browser describes the endpoint. ## Details [Section titled “Details”](#details) * **Stateless.** The server issues no session id and keeps nothing between requests, so a client can send `tools/list` or `tools/call` without an `initialize` first. Responses are JSON, not server-sent events. * **Errors.** A lookup the API refuses (an unknown user, a malformed address) comes back as a tool error carrying the API’s status and message, not as a protocol failure. * **Rate limits** are the free API’s. Each call reaches `api.ethos.network` with the client header `developers.ethos.network-mcp`. * **Only reads.** Nothing here writes. For reviews, vouches or XP tips an agent uses the full API with an [API key](/api-documentation/api-key-authentication). * **Listed** in the [MCP registry](https://registry.modelcontextprotocol.io) as `network.ethos/api`, where MCP clients and directories that read it find it. Need more than these five? The whole API is free with an `X-Ethos-Client` header; the [Vibe Coding Quickstart](/api-documentation/vibe-coding-quickstart) is written for an agent to read, and [Agents and x402](/api-documentation/agents-x402) covers the paid-per-request copies of the same lookups. # Vibe Coding Quickstart > Point your agent here to get started. Not intended for humans. ## Ethos API Project Setup Instructions [Section titled “Ethos API Project Setup Instructions”](#ethos-api-project-setup-instructions) You are setting up a new project that integrates with the Ethos Network API. ### 1. Environment Setup [Section titled “1. Environment Setup”](#1-environment-setup) Install Deno: `curl -fsSL https://deno.land/install.sh | sh` Create `deno.json` with tasks for dev, check, and any cron jobs needed. Deno documentation: ### 2. Project Structure [Section titled “2. Project Structure”](#2-project-structure) Create: ```plaintext src/ ethos-client.ts # API wrapper functions main.ts # Entry point .env.example # Document required env vars deno.json ``` ### 3. Ethos API Basics [Section titled “3. Ethos API Basics”](#3-ethos-api-basics) Base URL: `https://api.ethos.network/api/v2` Required header: `X-Ethos-Client` (identifies your app) All requests should include headers: `{ "X-Ethos-Client": "your-app-name" }` Documentation: * - Full API docs * - LLM summary: endpoint groups with descriptions * - LLM detailed reference: every endpoint with parameters and response shapes * - OpenAPI v3 spec ### 4. User Key Formats [Section titled “4. User Key Formats”](#4-user-key-formats) When looking up users, these formats work: * `address:0x...` - Ethereum address * `service:x.com:` - Twitter by ID * `service:x.com:username:` - Twitter by username * `service:discord:` - Discord To cite a person, link their profile page: `https://app.ethos.network/profile/x/` or `https://app.ethos.network/profile/
` ### 5. Example Endpoints [Section titled “5. Example Endpoints”](#5-example-endpoints) * GET `https://api.ethos.network/api/v2/score/address?address=0x...` - Get credibility score * GET `https://api.ethos.network/api/v2/user/by/address/{address}` - Get user profile See full endpoint list: `https://developers.ethos.network` ### 6. Authentication [Section titled “6. Authentication”](#6-authentication) Most read endpoints are public (no auth). For authenticated user actions and login integration: ### 7. Reference Examples [Section titled “7. Reference Examples”](#7-reference-examples) Study these repos for patterns: * ; * ; * ; * ; * ; *