Skip to main content
A snapshot is the unit of underwriting data on Guild. One snapshot per user per fetch. Signed, scoped, timestamped, verifiable. You fetch one when you decide. You verify the signature. You feed the JSON into your model. The fields are what they say they are.

Fetching

Response 200 with the snapshot JSON. Response time: median 95ms, p99 280ms. You can pass a ledger_window_days query parameter to override the consent’s default window (within the bounds of the granted scope). Useful if a consent allows up to 365 days but you only want the last 30 for a specific calculation:

The full payload

The shape is consistent — fields you don’t have scope to read are present but null (or absent for collections). This lets your code use the same parser regardless of which scopes the consent granted.

Field semantics

The signals are the heart of the snapshot. Detailed semantics so you can build your model against precise definitions.

Standing

Job/work signals

Cashflow signals

Ledger window (aggregated)

The ledger window is the user’s transaction summary over the requested time range. We don’t expose individual transactions — only aggregates. For traders, the ledger window also includes dailyAvgInflowKobo and distinctSendersLast30d.

KYC

Repayment history

If the user has taken loans through any Guild-integrated lender: This scope is privacy-sensitive. We aggregate across partners — you don’t see which partner extended the credit, only that someone did.

Signature verification

This is the part you must implement carefully. The signature covers a canonical JSON serialisation of the entire payload (except the signature field itself). We use Ed25519. Our public keys are at GET /partner/v1/keys:
We rotate keys quarterly with a 30-day overlap window. During overlap, snapshots may be signed with either the outgoing or incoming key. Verification steps:
1

Pull the keys

Cache for up to 4 hours. Don’t fetch per snapshot.
2

Look up the kid

The signature contains a kid reference. Find the matching public key.
3

Canonicalise the payload

Remove the signature field. Sort keys lexicographically at every level. Serialise with no extra whitespace.
4

Verify

Standard Ed25519 verification. If invalid, reject the snapshot — do not pass it to your underwriting model.
We provide reference implementations in Python, Node.js, and Go on the Partner Portal under “Resources.” Use those rather than implementing from scratch.

What’s not in a snapshot

Things you might expect but won’t find:
  • Transaction-level details. Only aggregates. (Privacy.)
  • Counterparty names. “11 unique counterparties” not “Adekunle, Olabisi, Funmi, …”. (Privacy.)
  • The user’s bank account number or BVN. We hold those. They don’t leave Guild. (Security.)
  • GPS coordinates or device IDs. We don’t collect them.
  • Voice transcripts or message contents. We have them; we don’t share them.
The snapshot is engineered for underwriting. Not surveillance.

Caching

A snapshot is a point-in-time read. You can cache it on your side for the duration of your underwriting decision. Don’t cache it indefinitely. A user’s standing tier can change daily; an underwriting decision made on stale data is bad for the borrower and bad for you. Reasonable cache TTL: the length of your decisioning window (e.g., if you decide within 5 minutes of fetch, cache for 5 minutes). If you need a fresh read, fetch a new snapshot. Each fetch is independent and signed with the timestamp.

Idempotency

Snapshot fetches are read-only and inherently idempotent. No Idempotency-Key header needed.

Errors

Next

Webhooks

Real-time notifications when consents change, tiers move, or repayments land.

Rate limits

Per-key throughput, bursts, and dedicated capacity options.