# AsterPay KYA Schema — composite trust + endpoint quality

**Version:** 1.1.0 — 2026-04-23
**Audience:** Endpoint-quality intelligence providers (e.g. SmartFlow Intelligence)
**Purpose:** define the data contract for plugging endpoint
quality scores into AsterPay's KYA (Know Your Agent) trust pipeline,
and for AsterPay returning a composite signal in a single combined
API call.

**Status v1.1.0 (2026-04-23):** SmartFlow Observatory is the first
endpoint-quality provider wired into KYA as the 8th component. The
combined endpoint is live — append `?endpoint={URL}` to
`/v1/agent/trust-score/{address}` or `/v1/agent/audit/{address}`.

Live endpoint: `GET https://x402.asterpay.io/v1/agent/trust-score/{address}`
Audit endpoint: `GET https://x402.asterpay.io/v1/agent/audit/{address}`
Framework docs: `GET https://x402.asterpay.io/v1/agent/framework`
Test vectors: `https://asterpay.io/.well-known/kya-test-vectors.json`
Audit challenge: `https://asterpay.io/.well-known/kya-audit-challenge.md`
This document: `https://asterpay.io/.well-known/kya-schema-v1.md`
Source: AsterPay private monorepo — `x402-api/src/services/kya.ts`, `x402-api/src/routes/kya.ts`

---

## 1. What AsterPay scores today (caller-side)

KYA produces a **trust score 0-100** for an EVM address, derived
from a deterministic rule-based formula (no ML, EU AI Act
limited-risk classification). Components:

| Component             | Max | Source                                                  |
|----------------------|-----|---------------------------------------------------------|
| `walletAge`           |  15 | tx-count-derived age estimate, Base RPC                 |
| `walletActivity`      |  15 | Base RPC tx count                                       |
| `sanctionsClean`      |  20 | Chainalysis (OFAC / EU / UN), binary gate               |
| `erc8004Identity`     |  20 | ERC-8004 registry on Base + InsumerAPI country attestation |
| `operatorKyb`         |  20 | manual whitelist > Coinbase KYC > ERC-8004 partial      |
| `transactionHistory`  |   5 | AsterPay payment history + Gitcoin Passport             |
| `trustBond`           |   5 | InsumerAPI attested USDC balance                        |
| `endpointQuality`     |   5 | **(optional, opt-in via `?endpoint=URL`)** SmartFlow Observatory endpoint quality score |
| **`total`**           | **100** | clamped sum (overflow capped — components sum to 105 with all 8 maxed) |

Tier mapping (`scoreToTier`):

| Score range | Tier         | Max per tx (USDC) | Max daily (USDC) |
|-------------|--------------|-------------------|------------------|
| 0-19        | `open`       | 1                 | 10               |
| 20-49       | `verified`   | 1,000             | 5,000            |
| 50-79       | `trusted`    | 10,000            | 50,000           |
| 80-100      | `enterprise` | 1,000,000         | 10,000,000       |

---

## 2. AsterPay response shape (current production)

`GET /v1/agent/trust-score/{address}` →

```json
{
  "success": true,
  "data": {
    "address": "0x...",
    "trustScore": 67,
    "tier": "trusted",
    "maxPerTx": 10000,
    "maxDaily": 50000,
    "breakdown": {
      "walletAge": 12, "walletActivity": 10, "sanctionsClean": 20,
      "erc8004Identity": 16, "operatorKyb": 0,
      "transactionHistory": 4, "trustBond": 5,
      "endpointQuality": 0,
      "total": 67
    },
    "identity": { "registered": true, "agentId": 16850, "owner": "0x...", "metadataUri": "ipfs://..." },
    "screening": { "allowed": true, "sanctioned": false, "blacklisted": false, "reason": null },
    "wallet": { "address": "0x...", "nativeBalance": 0.12, "txCount": 84, "estimatedAgeDays": 168, "usdcBalance": 540.0, "hasActivity": true },
    "flags": ["SANCTIONS_CLEAN", "ERC8004_VERIFIED", "AGENT_#16850", "GITCOIN_PASSPORT_VERIFIED", "INSUMER_USDC_ATTESTED"],
    "checkedAt": "2026-04-21T14:00:00.000Z",
    "ttlSeconds": 300,
    "transparency": {
      "automated_decision": true,
      "system": "KYA Trust Score",
      "methodology": "rule-based",
      "disclosure": "...",
      "human_review": "...",
      "documentation": "https://x402.asterpay.io/v1/agent/framework"
    }
  },
  "_meta": {
    "api": "AsterPay Know Your Agent (KYA)",
    "version": "1.0.0",
    "eu_ai_act": { "classification": "limited-risk", "article_50_transparency": true, "methodology": "deterministic rule-based scoring (no ML)" }
  }
}
```

---

## 3. Composite endpoint quality (8th KYA component, LIVE)

Append `?endpoint={URL}` to `trust-score` or `audit`:

```
GET https://x402.asterpay.io/v1/agent/trust-score/{address}?endpoint=https://x402.example.com
GET https://x402.asterpay.io/v1/agent/audit/{address}?endpoint=https://x402.example.com
```

When the query param is set, AsterPay calls SmartFlow Observatory's
`/v1/quality?endpoint={URL}` API, verifies the HMAC-SHA256 signature
on the response, and folds the score into KYA as the 8th component.
Without the param, scoring is unchanged (backward-compatible).

### URL normalization (caller and AsterPay agree)

- Lowercase host
- Strip default ports (`:80` for `http`, `:443` for `https`)
- Strip trailing slash from pathname (including the implicit root `/`)

Examples (all collapse to the same key):
- `https://API.Example.com:443/v1/`
- `https://api.example.com/v1`
- `https://api.example.com/v1/`

### Score → KYA points mapping (agreed bucketing 5/4/2/0)

| SmartFlow `score` | KYA points | Flag                                |
|-------------------|------------|-------------------------------------|
| 80 – 100          | 5          | `ENDPOINT_QUALITY_EXCELLENT`        |
| 50 – 79           | 4          | `ENDPOINT_QUALITY_GOOD`             |
| 20 – 49           | 2          | `ENDPOINT_QUALITY_POOR`             |
| 0  – 19           | 0          | `ENDPOINT_QUALITY_BROKEN`           |
| unavailable / unsigned | 0     | (no flag, degrades silently)        |

### Response shape (additional `endpointQuality` block)

When `?endpoint=` is supplied, the response gains an `endpointQuality`
block. The `source` and `attribution_url` fields **stay visible to
end callers** by design — that is the brand surface providers like
SmartFlow Observatory trade for being bundled into AsterPay's
composite signal. Do not strip them when proxying.

```json
{
  "data": {
    "...": "...",
    "breakdown": {
      "...": "...",
      "endpointQuality": 4,
      "total": 71
    },
    "endpointQuality": {
      "score": 75,
      "kyaPoints": 4,
      "url": "https://x402.example.com",
      "originalUrl": "https://x402.example.com/",
      "source": "smartflow-observatory",
      "attribution_url": "https://smartflowproai.com",
      "lastScannedAt": "2026-04-23T06:00:08.187Z",
      "sampleSize": 12,
      "signatureVerified": true,
      "cached": false
    }
  }
}
```

### Audit payload (`/v1/agent/audit`) extra

`audit.inputs_used.endpoint_quality_summary` is non-null when an endpoint
was supplied, and contains: `requested_url`, `normalized_url`,
`smartflow_score`, `kya_points`, `sample_size`, `last_scanned_at`,
`signature_verified`, `source`, `attribution_url`.

---

## 4. Auth + caching

- **Today, free tier:** no auth, public reads, 5-min server-side
  cache per address. Rate limit ~60 req/min per IP, lift on request.
- **For SmartFlow ingestion of AsterPay scores:** continue as anon
  reads, or we can issue an API key for unrate-limited reads + push
  webhooks when scores change tier.
- **For AsterPay ingestion of SmartFlow snapshots:** prefer pull
  (we cache 5-15 min), fallback push webhook to `POST
  /v1/external/smartflow/snapshot` (TBD endpoint, signed payload).

---

## 5. EU AI Act + GDPR notes (so we don't have to redo this later)

- KYA classified **limited-risk** (Article 50 transparency
  obligations only) because the scoring is **deterministic
  rule-based**, no ML, no profiling in the GDPR Art. 22 sense beyond
  what we already disclose in `transparency` block.
- If SmartFlow's scores are themselves rule-based / deterministic
  → no change.
- If SmartFlow's scores are ML-derived → we'll surface that in
  the combined endpoint's `transparency` block and disclose
  upstream model class. Doesn't change EU AI Act classification of
  the AsterPay component, but matters for end-merchant disclosure.
- All scores are pseudonymous (wallet address only). No PII
  transferred between SmartFlow and AsterPay in either direction.

---

## 6. Locked decisions (was "open items" in v1.0.0)

All five items locked with SmartFlow Intelligence on 2026-04-22:

1. **Endpoint identifier** → URL string. Both sides normalize: lowercase
   host, strip trailing slash, strip default ports (see §3).
2. **Score range** → 0–100. AsterPay maps to 5/4/2/0 KYA points (see §3).
3. **Refresh cadence** → AsterPay caches the SmartFlow response for
   1 hour (`SMARTFLOW_CACHE_TTL_SECONDS`, env-overridable). Underlying
   data refreshes continuously in SmartFlow's observatory; our cache
   is the only freshness control on AsterPay's side.
4. **Combined endpoint owner** → AsterPay-hosted. Implemented as a
   query-param extension to existing routes (no new routes), so
   `?endpoint=URL` is opt-in and backward-compatible.
5. **Co-marketing / attribution** → SmartFlow attribution preserved
   verbatim in the `endpointQuality.source` (`"smartflow-observatory"`)
   and `endpointQuality.attribution_url` (`"https://smartflowproai.com"`)
   fields of every response that uses the 8th component. Do not strip.

---

## 7. Reference

- Production scoring code (single file, exported): `x402-api/src/services/kya.ts` — `calculateTrustScore()`
- SmartFlow client (HMAC-verify, cache, URL normalize): `x402-api/src/services/smartflow.ts`
- HTTP routes: `x402-api/src/routes/kya.ts`
- Unit tests + golden vectors: `x402-api/src/services/kya-scoring.test.ts` + `x402-api/test-data/kya-test-vectors.json`
- Smoke test (live signed fetch): `x402-api/scripts/smartflow-smoke-test.ts`
- Public test vectors mirror: `https://asterpay.io/.well-known/kya-test-vectors.json`
- Audit challenge doc (third-party verification): `https://asterpay.io/.well-known/kya-audit-challenge.md`
- Framework JSON: `GET https://x402.asterpay.io/v1/agent/framework`

## 8. Try it

```bash
# baseline KYA (no endpoint)
curl https://x402.asterpay.io/v1/agent/trust-score/0xYourAddress

# composite KYA + SmartFlow endpoint quality (8th component)
curl "https://x402.asterpay.io/v1/agent/trust-score/0xYourAddress?endpoint=https://x402.example.com"

# audit version (full inputs + breakdown for third-party verification)
curl "https://x402.asterpay.io/v1/agent/audit/0xYourAddress?endpoint=https://x402.example.com"
```

Anything missing or unclear, ping me — happy to iterate.

— Petteri / AsterPay
