REST API — Sprite CRUD & Verification
iris intermediate 5 min read
ELI5
The sprite API is like a library’s card catalog system. You can add new books (create), look up details (get), update information (update), remove books (delete), and verify that a book hasn’t been secretly swapped for a fake (fingerprint check).
Technical Deep Dive
Endpoint Summary
| Method | Path | Operation | Status Codes |
|---|---|---|---|
POST | /v1/sprites | createSprite | 201, 400, 409 |
GET | /v1/sprites/{id} | getSprite | 200, 404 |
PUT | /v1/sprites/{id} | updateSprite | 200, 400, 404, 409 |
DELETE | /v1/sprites/{id} | deleteSprite | 204, 404, 409 |
GET | /v1/sprites/{id}/fingerprint | verifySpriteFingerprint | 200, 404 |
Create Sprite (POST /v1/sprites)
sequenceDiagram participant Client participant Router as sprites.py participant Registry as SpriteRegistry participant Engine as FingerprintEngine
Client->>Router: POST /v1/sprites Note over Client,Router: Content-Type: application/json OR application/x-yaml Router->>Router: Parse body → SpriteCreate Router->>Router: validate_sprite_name() Router->>Registry: Check (name, version) duplicate alt Duplicate exists Registry-->>Router: Conflict Router-->>Client: 409 Name+Version conflict else Unique Router->>Engine: compute_fingerprint(sprite_data) Engine-->>Router: blake3:64hex Router->>Registry: create(sprite_data, fingerprint) Registry->>Registry: Generate UUID + timestamp Registry-->>Router: Sprite (with id, fingerprint, created) Router-->>Client: 201 Sprite endAccepts: application/json or application/x-yaml
Returns: 201 Created with full Sprite object (server-generated id, fingerprint, metadata.created)
Update Sprite (PUT /v1/sprites/{id})
sequenceDiagram participant Client participant Router as sprites.py participant Registry as SpriteRegistry
Client->>Router: PUT /v1/sprites/{id} Router->>Registry: get_by_id(id) alt Not found Registry-->>Router: None Router-->>Client: 404 else Found Router->>Router: Validate version > current (packaging.version) alt Version not greater Router-->>Client: 409 Version conflict else Valid update Router->>Router: Recompute fingerprint Router->>Registry: update(id, data, fingerprint) Registry-->>Router: Updated Sprite Router-->>Client: 200 Sprite end endRules:
idandnameare immutableversionmust be strictly greater than current (usespackaging.versioncomparison)- Fingerprint is always recomputed
- Previous version is recorded in registry history
Delete Sprite (DELETE /v1/sprites/{id})
flowchart TD A["DELETE /v1/sprites/{id}"] --> B{"Sprite in active council?"} B -->|Yes| C["409 Conflict"] B -->|No| D{"Protected?"} D -->|Yes| E{"force=true?"} E -->|No| F["409 Protected sprite"] E -->|Yes| G["Delete ✓"] D -->|No| G G --> H["204 No Content"]Rules:
- Rejected (409) if sprite is referenced by any active council
- Protected sprites require
?force=truequery parameter - Returns
204 No Contenton success
Verify Fingerprint (GET /v1/sprites/{id}/fingerprint)
sequenceDiagram participant Client participant Router as sprites.py participant Registry as SpriteRegistry participant Engine as FingerprintEngine
Client->>Router: GET /v1/sprites/{id}/fingerprint Router->>Registry: get_by_id(id) alt Not found Registry-->>Router: None Router-->>Client: 404 else Found Router->>Engine: verify_fingerprint(sprite, stored_hash) Engine->>Engine: Strip id/created/fingerprint → canonical → Blake3 Engine-->>Router: verified: true/false Router-->>Client: 200 Fingerprint {verified, stored, computed, verified_at} endReturns:
{ "sprite_id": "uuid", "algorithm": "blake3", "stored_hash": "a1b2c3...", "computed_hash": "a1b2c3...", "verified": true, "verified_at": "2026-04-27T12:00:00Z"}Registry Index Structure
erDiagram SPRITE_REGISTRY { UUID id PK string name string version string role json capabilities text system_prompt boolean protected boolean gate_authority json metadata string fingerprint_algorithm string fingerprint_hash datetime created } NAME_VERSION_INDEX { string name string version UUID sprite_id FK } SPRITE_REGISTRY ||--o{ NAME_VERSION_INDEX : "indexed by"The SpriteRegistry maintains two data structures:
dict[UUID, Sprite]— primary storage keyed by UUIDdict[(name, version), UUID]— uniqueness index for duplicate detection
Key Terms
- SpriteCreate → The request model for creating a sprite (no
idorfingerprint; server generates these) - SpriteUpdate → Partial update model;
nameandidare immutable;versionmust monotonically increase - Name+version conflict → Attempting to create a sprite with an existing
(name, version)pair returns 409 - Protected sprite → A sprite that cannot be deleted without
?force=trueand cannot be bypassed in chains - Fingerprint verification → Recomputing the Blake3 hash from canonical data and comparing with stored hash
Q&A
Q: Can I create a sprite with the same name but different version?
A: Yes. The uniqueness constraint is on (name, version), not just name. SOL-FORGE v1.0.0 and SOL-FORGE v2.0.0 can coexist.
Q: What content types does the create endpoint accept?
A: application/json and application/x-yaml. The endpoint inspects the Content-Type header to determine the parser.
Q: Can I change a sprite’s name via PUT?
A: No. name is immutable. If you need a differently named sprite, create a new one.
Q: How does version comparison work?
A: The service uses packaging.version to compare versions. 2.0.0 > 1.10.0 > 1.9.9 > 1.0.0-alpha.
Q: Is fingerprint verification case-sensitive?
A: No. The engine performs case-insensitive hex comparison: A1B2 == a1b2.
Examples
The sprite API is like a government ID system:
- POST = Applying for a new passport (you provide info, government assigns ID number and issues the document)
- GET = Showing your passport at border control (lookup by ID number)
- PUT = Renewing your passport (new version number, new photo, same ID number)
- DELETE = Surrendering your passport (only allowed if you have no active visas — i.e., not in any active council)
- Fingerprint verify = The hologram check — border control shines a UV light to verify the passport hasn’t been forged
neighbors on the map
- REST API — Council Creation & Chain Execution creating a council via the API
- Python SDK & CLI writing Python scripts that interact with IRIS
- TypeScript SDK & MCP Client building web apps that interact with IRIS