/api/drd/local/search

GET

Searches the local replica of the Distributed Resource Directory. Pure local SQL — no RAIDA round-trip, so results are instant once the replica has synced. All parameters are optional and combine with AND. The local replica may lag the live directory; use /api/drd/user/get for the authoritative per-record read.

Parameters

Name Type Required Description
first_name string No Case-insensitive prefix match on first name.
last_name string No Case-insensitive prefix match on last name.
name string No Prefix match against first or last name (convenience filter).
description string No Case-insensitive substring match against the decoded profile description text (not base64).
class integer No Exact denomination code of the record's coin (-8 to 6).
class_min / class_max integer No Denomination range (-8 to 6).
symbol integer No 0–255; matches either symbol slot. May be given twice (symbol=7&symbol=42) so the record must show both values (either slot order). symbol_b is an accepted alias for the second value.
symbol1 / symbol2 integer No Slot-exact first / second avatar symbol (0–255).
class_rejection integer No Exact class-rejection code (-8 to 6).
class_rejection_min / class_rejection_max integer No Class-rejection range (-8 to 6).
fee_min / fee_max string No Inbox fee range as decimal CC strings (same rules as /api/drd/user/post fee).
sn integer No Exact serial number.
sn_min / sn_max integer No Serial-number range.
created_after / created_before integer No Unix seconds filter on created_at.
updated_after / updated_before integer No Unix seconds filter on updated_at.
include_deleted boolean No Include tombstoned records. Default false.
sort string No name (default), created_at, updated_at, fee, or class.
order string No asc or desc.
limit integer No Page size. Default 50, max 500.
offset integer No Paging offset. Default 0.

Responses

Success Response (200)

Returns a page of matching users plus the total match count. Each user object uses the same fields as /api/drd/user/get (including websafe-base64 description), plus deleted and a formatted QMail address (null when the denomination is not a QMail class 0–4).

{
    "command": "drd-local-search",
    "success": true,
    "count": 1,
    "total": 1,
    "users": [
        {
            "denomination": 1,
            "serial_number": 9840,
            "inbox_fee": "0.5",
            "inbox_fee_units": 50000000,
            "first_symbol": 3,
            "second_symbol": 14,
            "class_rejection": 0,
            "created_at": 1783741315,
            "updated_at": 1783741315,
            "account_age_seconds": 86400,
            "first_name": "Alice",
            "last_name": "Example",
            "description": "Q2xvdWRDb2luIGRldmVsb3Blcg",
            "deleted": false,
            "address": "38.112@byte"
        }
    ]
}

count is the number of rows in this page; total is the full match count for the filter (for paging UI). address is built only when denomination is 0–4 and the serial fits three bytes; otherwise it is JSON null.

Error Responses

400 Bad Request

Invalid filter value (out-of-range class/symbol, bad fee decimal, unknown sort/order, non-numeric timestamp, etc.).

{
    "error": true,
    "message": "Invalid sort (name|created_at|updated_at|fee|class)",
    "code": 400
}

503 Service Unavailable

The local replica store is not open (not initialized).

{
    "error": true,
    "message": "Local DRD replica not initialized",
    "code": 503
}

Examples

cURL Example

curl -X GET "http://localhost:8080/api/drd/local/search?name=Ali&limit=10&sort=name&order=asc"

JavaScript Example

const params = new URLSearchParams({
    name: 'Ali',
    limit: 10,
    sort: 'updated_at',
    order: 'desc'
});

fetch(`http://localhost:8080/api/drd/local/search?${params}`)
    .then(r => r.json())
    .then(data => {
        if (data.success) {
            console.log(`${data.count} of ${data.total} matches`);
            data.users.forEach(u =>
                console.log(`${u.first_name} ${u.last_name} — ${u.address ?? 'no QMail address'}`));
        } else if (data.code === 503) {
            console.log('Replica not ready — call /api/drd/local/sync first');
        }
    });

Python Example

import requests

url = 'http://localhost:8080/api/drd/local/search'
data = requests.get(url, params={
    'name': 'Ali', 'limit': 10, 'sort': 'name', 'order': 'asc'
}).json()

if data.get('success'):
    for u in data.get('users', []):
        print(f"{u['first_name']} {u['last_name']}: {u.get('address')}")
elif data.get('code') == 503:
    print('Local DRD replica not initialized')

Notes

  • This endpoint never fans out to RAIDA; it only reads the local store. Kick a sync with /api/drd/local/sync and check health with /api/drd/local/status.
  • The local replica may lag the live directory. For a single authoritative record, call /api/drd/user/get.
  • Response description is websafe base64 of the stored UTF-8 text (same as live get/search); the description query param is plain text for substring match.
  • An empty match set is still 200 with count: 0 and total: 0.