For developers

Add fraglets to
your service

Register for an API key, and start creating and consuming fraglets via the fraglet.org API. If you've integrated with Stripe or OpenAI, the pattern is the same: a prefixed key, Bearer auth, JSON in and out.

Getting started

Everything goes through the fraglet.org API. Register as a developer, get an API key, and you're ready.

Register for an API key

Create a developer account and receive an API key. The key is shown once, so store it somewhere safe.

You can also register programmatically via POST /register with a JSON body containing email, name, and optionally organisation. The response includes your api_key and developer_id. Registration is rate-limited to 5 requests per hour per IP.

Quickstart

Three steps to start using fraglets in your service.

1

Get an API key

Register as a developer at fraglet.org. You'll receive an API key prefixed frag_live_. Use it as a Bearer token in the Authorization header on every request.

2

Create or fetch fraglets

POST /api/v1/fraglets to create a fraglet. The API generates the embedding automatically. GET /api/v1/fraglets/{id} to fetch one. GET /api/v1/fraglets/discover to browse open fraglets by domain.

3

Match against your catalogue

Fetch the fraglet with ?include_embedding=true to get the embedding vector. Use it with your existing vector database (pgvector, Pinecone, Qdrant, etc.) to find the items in your catalogue closest to the user's characteristics.

create_and_fetch.py
import requests

API_KEY = "frag_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
BASE = "https://api.fraglet.org/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# Create a fraglet — embedding generated server-side
fraglet = requests.post(f"{BASE}/fraglets", headers=HEADERS, json={
    "title": "Nocturnal jazz wanderer",
    "brief": "Late-night jazz devotee drawn to intimate venues.",
    "detail": "A deep appreciation for musicians who treat standards "
              "as starting points rather than destinations...",
    "category": "Contemporary jazz and fusion",
    "tags": ["jazz", "post-bop", "intimate-venues"],
    "domain": "music",
    "visibility": "open"
}).json()

print(fraglet["id"])        # UUID
print(fraglet["embedding"]) # null (not included by default)

# Fetch it back with embedding
fetched = requests.get(
    f"{BASE}/fraglets/{fraglet['id']}?include_embedding=true",
    headers=HEADERS
).json()

# Match against your catalogue
results = your_vector_db.query(
    vector=fetched["embedding"],  # 1536-dim vector
    top_k=20,
    threshold=0.3
)
match_items.sql
-- pgvector: rank your catalogue items
-- by similarity to the fraglet embedding

SELECT id, title, description,
  1 - (embedding <=> $1) AS similarity
FROM your_items
WHERE 1 - (embedding <=> $1) > 0.3
ORDER BY embedding <=> $1
LIMIT 20;
create_and_fetch.js
const API_KEY = 'frag_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const BASE = 'https://api.fraglet.org/api/v1';
const headers = { Authorization: `Bearer ${API_KEY}` };

// Create a fraglet
const fraglet = await fetch(`${BASE}/fraglets`, {
  method: 'POST',
  headers: { ...headers, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    title: 'Nocturnal jazz wanderer',
    brief: 'Late-night jazz devotee drawn to intimate venues.',
    detail: 'A deep appreciation for musicians who treat standards...',
    category: 'Contemporary jazz and fusion',
    tags: ['jazz', 'post-bop', 'intimate-venues'],
    domain: 'music',
    visibility: 'open'
  })
}).then(r => r.json());

// Fetch with embedding included
const withEmbed = await fetch(
  `${BASE}/fraglets/${fraglet.id}?include_embedding=true`,
  { headers }
).then(r => r.json());

// Match against your catalogue
const results = await vectorDb.query({
  vector: withEmbed.embedding,
  topK: 20
});

Anatomy of a fraglet

Every fraglet follows the same schema, regardless of domain. Here is a real example from the music domain. Note: the embedding field returns null by default . Request it explicitly with ?include_embedding=true.

example fraglet: music domain
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "title": "Nocturnal jazz wanderer",
  "brief": "Late-night jazz devotee drawn to intimate venues and
    musicians who blur the line between composition and
    improvisation.",
  "detail": "A deep appreciation for musicians who treat standards
    as starting points rather than destinations. You gravitate
    toward small-combo recordings where you can hear the room,
    the breath between phrases, the moment a soloist decides to
    take a risk. Post-bop and modal jazz form the core, but you
    follow threads into ECM-style European jazz, spiritual jazz,
    and the London scene...",
  "additional": {
    "sub_profiles": [
      {"label": "Jazz", "examples": ["Ahmad Jamal", "Shabaka Hutchings"]},
      {"label": "Adjacent", "examples": ["Floating Points", "Khruangbin"]}
    ],
    "sonic_preferences": {
      "energy": "low-to-medium",
      "setting": "intimate venues"
    }
  },
  "category": "Contemporary jazz and fusion",
  "tags": ["jazz", "post-bop", "modal", "intimate-venues",
    "improvisation", "London-scene"],
  "domain": "music",
  "embedding": null,
  "parent_id": null,
  "visibility": "open",
  "created_at": "2026-03-15T14:30:00Z"
}
title string Human-readable label. Max 100 characters, sentence case.
brief string One or two sentence summary. Show this to users.
detail string Rich narrative (~150 words). Carries the most semantic weight in the embedding.
additional object Free-form JSON for domain-specific data. Structure varies by domain convention.
tags string[] Freeform descriptors. Useful for filtering before vector matching.
domain string Lowercase identifier: music, food, travel, etc. Fraglets are only comparable within the same domain.
embedding float[] High-dimensional vector. Server-generated, never client-supplied. Returned as null by default. Pass ?include_embedding=true to include it.
visibility enum private, selective, or open. Determines who can read and associate.
parent_id uuid|null Links to the fraglet this was derived from. null for originals. Enables edit history and adoption provenance.

Server metadata

The fraglet.org API publishes its capabilities at a well-known endpoint. No registration needed to check it.

GET https://api.fraglet.org/.well-known/fraglets
{
  "version": "1.0",
  "embedding": {
    "model": "text-embedding-3-large",
    "dimensions": 1536
  },
  "domains": ["music", "food", "travel"],
  "api_base": "https://api.fraglet.org/api/v1"
}

The metadata endpoint is public. No API key required. Use it to verify the embedding model before matching fraglet embeddings against your catalogue. Your catalogue items must be embedded with the same model for cosine similarity to be meaningful.

Consistent schema

Every fraglet conforms to the same structural schema. The core fields are always the same. Domain-specific extensions use the additional field.

Stable URIs

Every fraglet has a resolvable address: https://api.fraglet.org/api/v1/fraglets/{id}. Store the URI or the UUID. Both are stable and permanent.

Visibility controls

Three visibility levels govern who can read each fraglet. Private: only the creator. Selective: the creator plus specific developers granted access. Open: discoverable by anyone. Selective visibility lets users share fraglets with chosen services without making them globally discoverable.

API endpoints

All endpoints are at api.fraglet.org and require an API key as a Bearer token, except where noted.

The API handles fraglet storage, embedding generation, associations, and discovery. You provide the text fields; the server generates the embedding. Rate limiting is per-developer, per-endpoint category.

API reference
# Authentication
# All requests: Authorization: Bearer frag_live_xxxxxxxx

GET  /.well-known/fraglets            # Server metadata (public, no auth)
POST /register                        # Create developer account (no auth)

# Fraglets
POST   /api/v1/fraglets               # Create (embedding auto-generated)
GET    /api/v1/fraglets/{id}           # Read a fraglet
PATCH  /api/v1/fraglets/{id}           # Edit (private drafts only)
DELETE /api/v1/fraglets/{id}           # Delete (creator only, see below)
POST   /api/v1/fraglets/batch          # Batch read by IDs (max 50)
GET    /api/v1/fraglets/discover       # Browse open fraglets by domain

# Query parameters
GET /api/v1/fraglets/{id}?include_embedding=true  # Include embedding

# Associations
POST   /api/v1/fraglets/{id}/associate    # Associate with a fraglet
DELETE /api/v1/fraglets/{id}/associate    # Disassociate

# Grants (selective visibility)
POST   /api/v1/fraglets/{id}/grants              # Grant a developer read access
DELETE /api/v1/fraglets/{id}/grants/{dev_id}     # Revoke a grant
GET    /api/v1/fraglets/{id}/grants              # List grants (creator only)

# Jackets
POST   /api/v1/jackets                   # Create jacket
GET    /api/v1/jackets/{id}              # Read a jacket
PATCH  /api/v1/jackets/{id}              # Update (immutability enforced)
DELETE /api/v1/jackets/{id}              # Delete
POST   /api/v1/jackets/{id}/fraglets     # Add fraglets to jacket
DELETE /api/v1/jackets/{id}/fraglets     # Remove fraglets from jacket
GET    /api/v1/jackets/discover          # Browse open jackets
GET    /api/v1/jackets/mine              # List your jackets
POST   /api/v1/jackets/{id}/associate    # Associate with a jacket
DELETE /api/v1/jackets/{id}/associate    # Disassociate from a jacket
POST   /api/v1/jackets/{id}/adapt        # Fork a jacket

# Developer
GET    /api/v1/users/me/fraglets       # List your associated fraglets

Creating a fraglet automatically associates the creator with it. Private drafts are editable. You can PATCH a fraglet if it is private and no other developer is associated with it. Once a fraglet is shared or published, it becomes immutable. To "edit" an immutable fraglet, create a new one with parent_id set to the original's ID.

DELETE is also restricted: the creator can only delete a fraglet if no other developers are associated. To withdraw from a shared fraglet you created, set its visibility to private via PATCH. Embeddings are not included in responses by default. Pass ?include_embedding=true to request them.

Jackets are named collections of fraglets representing personas. They follow the same immutability pattern: once other developers associate, the composition is frozen. Use POST /{id}/adapt to fork a jacket with changes. Jacket associations support follow mode (live-tracking the current composition) and snapshot mode (frozen at association time).

Selective sharing via grants. When a fraglet has selective visibility, the creator can grant specific developers read access using POST /api/v1/fraglets/{id}/grants with {"developer_id": "..."}. The granted developer can then fetch the fraglet as if it were open — but it stays off public discovery. Grants are per-fraglet, per-developer, and revocable at any time. This is the recommended approach for cross-service use: users share fraglets with the services they choose, without making them globally visible.

MCP integration

AI agents interact with fraglets as MCP tools. No SDK or API client needed.

The fraglet MCP server exposes the full lifecycle as tools: list_my_fraglets, create_fraglet, discover_fraglets, select_fraglets (the picker), create_jacket, list_my_jackets, associate_with_fraglet, adapt_jacket, and more.

The picker (select_fraglets) is the key tool. Given an intent, it selects which fraglets are relevant at what level of detail. It accepts an optional jacket_id to scope selection through a persona, with context mode (bias) or strict mode (hard filter).

Users set up MCP access at fraglet.com. The MCP server runs in stdio mode (local) and as a remote Streamable HTTP endpoint. Configuration is a single JSON snippet added to any MCP-compatible client.

Rate limits

Limits are per developer, per category, rolling window. Exceeding a limit returns 429 Too Many Requests.

Reads 200/hour GET fraglets by ID, batch reads
Creates 30/hour POST new fraglets
Updates 30/hour PATCH and DELETE fraglets
Discovery 100/hour GET /discover endpoint
Associations 60/hour Associate and disassociate
Registration 5/hour POST /register (per IP, no auth)

Error responses

All errors return JSON with a detail field explaining the problem.

401 Unauthorized Missing or invalid API key.
403 Forbidden You are not the creator of this fraglet, or lack permission for this action.
404 Not Found Fraglet does not exist or is not visible to you.
409 Conflict Immutability violation (editing a shared fraglet), duplicate registration, or deleting a fraglet others are associated with.
422 Validation Error Invalid request body. Missing required fields, bad types, or constraint violations.
429 Too Many Requests Rate limit exceeded. Back off and retry.
example error response
{
  "detail": "Cannot edit fraglet: other developers are associated"
}

Specification and guides

The full technical documentation for building conforming implementations.

Developer questions

Do I need to run my own infrastructure?

No. The fraglet.org API handles storage, embedding generation, associations, and discovery. You just need an API key and an HTTP client. The only infrastructure you need is your own catalogue with vector embeddings if you want to match fraglets against your items.

What embedding model does fraglet.org use?

fraglet.org currently uses OpenAI's text-embedding-3-large at 1536 dimensions. Check api.fraglet.org/.well-known/fraglets for the current model and dimensions. Your catalogue items need to be embedded with the same model for cosine similarity to work.

What if my catalogue uses a different embedding model?

You can re-embed the fraglet's text fields (detail, tags, additional) using your own model. The text is always available; the server-generated embedding is a convenience for same-model matching.

How does authentication work?

Register as a developer and receive an API key prefixed frag_live_. Include it as a Bearer token in every request: Authorization: Bearer frag_live_xxx. Keys are shown once at creation, so store them securely. The /.well-known/fraglets metadata endpoint is the only public endpoint that doesn't require a key.

Are fraglets mutable?

Private drafts are editable. You can PATCH a fraglet if it is still private and no other developer has associated with it. Once a fraglet is shared, published, or associated with by others, it becomes immutable. To "edit" an immutable fraglet, create a new one with parent_id set to the original's ID. This means if you cache a shared fraglet, it will never change out from under you. Derivation chains let you trace how a taste profile has evolved.

What is the association model?

Users don't "own" fraglets. They associate with them. Multiple users can associate with the same fraglet. This enables the adoption pattern: a music venue publishes a fraglet describing its ideal audience, and users associate with it. Associations are managed server-side, not in the fraglet entity itself.

What are jackets?

Named collections of fraglets representing personas for different situations. A jacket is cross-domain: a date-night jacket might combine food, music, and travel fraglets. Jackets follow the same immutability pattern as fraglets: once others associate, the composition is frozen. Use the adapt endpoint to fork a jacket with changes.

Can my agent use fraglets?

Yes. Configure the fraglet MCP server in any MCP-compatible client and your agent gets tools for reading, creating, discovering, and selecting fraglets. The picker (select_fraglets) is the primary tool: it selects relevant fraglets for a given intent at the right detail level. Users set up MCP access at fraglet.com.

Is the fraglet pattern open?

Yes. The schema, protocol, and pattern are open for anyone to implement. The format specification and reference implementation guide are publicly available. There is no registration, licence fee, or central authority.