# MaterialGraph for developers

> Read MaterialGraph over REST, MCP and the `mg` CLI: search and read sourced records of architectural materials across every brand. Private beta: not yet available; API keys on request.

## Reading the record

- Preserve returned variant ids verbatim — they are opaque tokens, never parse or construct them.
- Absent means unknown, never false.
- Results are pages, not corpora: never report a page size as a total.
- Where a read states a value's confidence or Value Source, report the value as a claim, not a certainty.
- Color values are measured from product imagery unless their Value Source is brand, material_bank or samplize — report measured color as visual likeness, never as a stated color specification.
- Compliance and fire-classification data is advisory: it is what the brand declares, bounded by coverage, and never a determination for an authority having jurisdiction.
- Samplize is a sampling channel, never a brand: it prints other manufacturers' colors and makes nothing itself.

## Quickstart

1. Verify the key. Every integration runs this first:

```bash
curl https://beta.materialgraph.com/api/v1/whoami \
  -H "Authorization: Bearer $MG_API_KEY"
```

2. Search:

```bash
curl -X POST https://beta.materialgraph.com/api/v1/variants/search \
  -H "Authorization: Bearer $MG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "sage green wall tile",
    "limit": 5,
    "include": ["image"]
  }'
```

3. Read one variant: `GET /api/v1/variants/{variantId}` returns it compact; name `attributes` and `blocks` (comma-separated) to add their values. The login-free page `/materials/{variantId}` is the full record: it embeds schema.org JSON-LD and answers `Accept: text/markdown` with the same record as Markdown.

## Transports

- **REST**: `/api/v1`, OpenAPI 3.1 at [/openapi.yaml](/openapi.yaml), 42 operations.
- **MCP**: `POST /mcp`, stateless Streamable HTTP with the same bearer key: `claude mcp add --transport http materialgraph https://beta.materialgraph.com/mcp --header "Authorization: Bearer mg_…"`. 18 read tools.
- **CLI**: `mg`, JSON out and NDJSON in pipes, with `mg schema introspect "<command>"` before acting.

## Auth, keys, and rate limits

- Auth: `Authorization: Bearer mg_<read|compose|source|ingest|write|admin>_<random>` or `X-API-Key`. Every key grants `mg:read`.
- Keys are provisioned by the MaterialGraph team today. Operators mint a scoped `mg_read_*` key from the operator desk; external partners request one at [/developers#get-a-key](/developers#get-a-key).
- Every `/api/v1` response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`. Honor `X-RateLimit-Reset` before retrying a 429. Limits are per principal per bucket:

  - `default` — 600 requests per minute
  - `embed` — 10 requests per minute
  - `reference` — 120 requests per minute

## Errors

Every `/api/v1` error is an RFC 7807 problem document (`application/problem+json`) with `type`, `title`, `status`, `detail`, `is_retriable`, `suggestions` and `trace_id`. Each `type` dereferences to a page of the [error catalog](/errors.md).

## Public REST

#### Search

- `POST /api/v1/search/palettes/extract` — Extract a named color palette from an uploaded image
- `GET /api/v1/search/colors/resolve` — Resolve a color name or phrase — 'sage', a paint name — to a hex

#### Color

- `GET /api/v1/colors/nearest-paints` — Nearest Samplize catalogue paints for up to twelve hexes
- `GET /api/v1/colors/profiles` — The color palette of up to 8 categories in one call - by frequency, or spread for visual distinctness
- `GET /api/v1/colors/provenance` — Which paint brands publish a color value and which do not — declared by the manufacturer versus derived from imagery, per brand
- `GET /api/v1/colors/consistency` — Whether a brand's published color hex agrees with its published light reflectance — and whether the two are independent enough for the question to mean anything

#### Variants

- `GET /api/v1/variants/{variantId}` — One variant, compact: name, code, product, brand, category and image, plus the attributes and blocks you name
- `GET /api/v1/variants/{variantId}/assets` — A variant's images and files, filtered and paged, each with its role, availability and URL
- `GET /api/v1/variants` — List variants by a structured filter tree — attributes, category, brand, lifecycle, and up to 100 explicit ids
- `POST /api/v1/variants/facets` — Count variants per attribute value under the same filter tree, for a filter UI's options
- `POST /api/v1/variants/search` — Find variants from plain words - the query is read into filters, run through list_variants, and answered with what was understood beside the page
- `GET /api/v1/variants/by-color` — Find variants by color — swatch containment, whole-palette closeness, or a held set reranked by color
- `POST /api/v1/variants/by-vector` — Find variants by semantic or visual similarity to a description, an image, or both
- `GET /api/v1/variants/sampled-together` — Find the materials designers sampled together with one or more seeds, other brands first then the most projects, each with a reason
- `POST /api/v1/variants/resolve` — Resolve a manufacturer page URL, or a manufacturer code with a brandId, to a stored variant

#### Materials

- `GET /api/v1/materials/{variantId}/blocks` — Canonical blocks, field values and statuses, and missing attribute ids
- `GET /api/v1/materials/{variantId}/documents` — Paged technical documents for the owning Product, with exact Variant attribution and explicit source coverage
- `GET /api/v1/catalogs` — List retained catalog publications, their exact source scope, and product-processing status
- `GET /api/v1/catalogs/{catalogId}/pages` — List stable pages and representation availability for one catalog edition
- `GET /api/v1/catalogs/{catalogId}/references` — List every reviewed product/page reference in one retained catalog
- `GET /api/v1/catalog-pages/{pageId}/representation` — Read the retained representation receipt for one stable catalog page
- `POST /api/v1/catalogues/references` — Find exact, reviewed brand-publication pages for up to 200 material variants
- `GET /api/v1/catalogues/collections` — List product collections grouped by their source catalogue channel
- `GET /api/v1/catalogues/documents/{documentId}` — Resolve browser-safe access to the immutable publication behind a verified page reference

#### Pairings

- `GET /api/v1/materials/{variantId}/pairings` — Materials specified together on real projects first, color-similar top-up — every item labelled by source

#### Associations

- `GET /api/v1/applicability` — Manufacturer-declared finishes with exact Product or Variant grain and explicit source coverage
- `GET /api/v1/associated/finishes` — The finishes a manufacturer declares for a product — stated fact, with a true total alongside the page
- `GET /api/v1/associated/products` — The products a manufacturer declares a finish for — the same edge read from the other end

#### Catalog

- `GET /api/v1/catalog/generation` — Read the current catalogue generation
- `GET /api/v1/catalogues/samplize/products` — Page the Samplize sampling channel's published paint listings, version-pinned for completeness
- `GET /api/v1/catalog/attributes` — Browse attribute definitions, or find one by id, name, misspelling or meaning - 'double rubs'
- `GET /api/v1/catalog/enum-values` — Browse a value dictionary's allowed values, or find one by name, alias, misspelling or meaning - 'class a'
- `GET /api/v1/categories` — Browse or search the category tree of groups and product types
- `GET /api/v1/categories/{id}` — One category's place in the tree and the canonical concepts it relates to

#### Schema

- `GET /api/v1/schema/value-dictionaries` — Governed controlled vocabularies and canonical terms

#### Brands

- `GET /api/v1/brands` — List registered brands with product and variant counts

#### Sources

- `POST /api/v1/source-material` — Upload a source-material batch — a pile of files (PDF, text, images) the pipeline classifies

#### Runs

- `POST /api/v1/workflows/{workflowId}/runs` — Start a registered workflow as a validated, asynchronous Run
- `GET /api/v1/workflows/{workflowId}/runs/{runId}` — Read the caller-owned, redacted state of a Run
- `GET /api/v1/workflows/{workflowId}/runs/{runId}/events` — Read ordered, redacted events after a Run sequence cursor

#### Meta

- `GET /api/v1/whoami` — Echo the authenticated principal and scopes — verify your key
- `GET /api/v1/keys/usage` — See what this key has spent, by day and operation class

## Discovery

- [agents.md](/agents.md): Agent candidateMeaning rules and the callable public surface
- [OpenAPI](/openapi.yaml): Machine-readable public REST contract
- [MCP](/mcp): Live Streamable HTTP MCP endpoint
- [Developers](/developers): Human-readable API documentation
- [Schema](/schema): Canonical blocks, attributes, and verticals
- [Vocabulary](/schema/terms): The mg: vocabulary as JSON-LD; every attribute, block, unit, and dictionary IRI resolves
- [JSON-LD context](/schema/terms/context.jsonld): The @context of the record JSON-LD embedded in /materials/{variantId}
- [JSON Schema](/schemas/record.schema.json): Draft 2020-12 schema for a Variant Record
- [Errors](/errors): Problem-type catalog for /api/v1 errors
- [llms-full.txt](/llms-full.txt): Extended agent-oriented documentation
- [Agent Skills](/.well-known/agent-skills/index.json): Agent Skills discovery index (v0.2.0): each mg CLI skill as a SKILL.md, with its sha256 digest
