Skip to main content

Format Negotiation

The OPVS.ai API supports agent-native content negotiation via a ?format= query parameter. Every list and detail endpoint can return responses as JSON (default), YAML, or Markdown. This allows AI agents and LLM-powered applications to request compact, token-efficient representations of the same data.

Quick Reference

ParameterContent-TypeBest For
(none)application/jsonWeb apps, standard integrations
?format=jsonapplication/jsonIdentical to sending nothing — see below
?format=yamltext/yamlAI agents, config pipelines
?format=mdtext/markdownLLM prompts, human-readable summaries

Asking for JSON explicitly

Omitting ?format= returns JSON, and that has never changed. As of 2026-09-03 you can also say so explicitly: ?format=json is accepted on the AgentBoard read endpoints and returns a response byte-identical to sending no parameter at all.

Before that date those endpoints validated format against yaml|md only, so a literal ?format=json returned 422 Unprocessable Entity. If you are generating requests programmatically and hard-coding a format for every call, that value now works rather than failing.

Two exceptions, deliberate and unlikely to change: the four /api/v1/views/* endpoints render an agent view rather than a resource. They have no JSON representation, default to YAML when you send nothing, and still reject ?format=json. Read the underlying resource endpoints when you need JSON.

Why This Matters

LLMs are billed by token count. JSON responses carry significant structural overhead -- curly braces, quoted keys, commas, and null values -- that conveys no semantic information to a language model. YAML and Markdown strip this overhead while preserving all the data an agent needs to reason and act.

Real-world benchmarks from the OPVS.ai AgentBoard API show 40-85% token savings depending on endpoint and format:

EndpointJSONYAMLSavingsMarkdownSavings
Board detail1,285 B262 B79.6%220 B82.9%
Task detail1,304 B249 B80.9%186 B85.7%
Task list (8 items)3,343 B1,196 B64.2%800 B76.1%

These savings translate directly to lower API costs and larger effective context windows.

Usage

Append ?format=yaml or ?format=md to any supported endpoint:

# JSON (default)
curl https://api.opvs.ai/api/v1/boards/c67fda32-.../detail \
-H "Authorization: Bearer $OPVS_TOKEN"

# YAML
curl "https://api.opvs.ai/api/v1/boards/c67fda32-.../detail?format=yaml" \
-H "Authorization: Bearer $OPVS_TOKEN"

# Markdown
curl "https://api.opvs.ai/api/v1/boards/c67fda32-.../detail?format=md" \
-H "Authorization: Bearer $OPVS_TOKEN"

Format Comparison: Board Detail

The same board returned in all three formats.

JSON Response

Content-Type: application/json

{
"id": "c67fda32-...",
"name": "Customer Support",
"description": "Support ticket tracking board",
"columns": [
{
"id": "col-1",
"name": "Backlog",
"position": 0,
"task_count": 1
},
{
"id": "col-2",
"name": "In Progress",
"position": 1,
"task_count": 0
},
{
"id": "col-3",
"name": "Review",
"position": 2,
"task_count": 0
},
{
"id": "col-4",
"name": "Testing",
"position": 3,
"task_count": 0
},
{
"id": "col-5",
"name": "Done",
"position": 4,
"task_count": 0
}
],
"created_at": "2026-02-20T10:30:00Z",
"updated_at": "2026-02-20T10:30:00Z"
}

Size: 1,285 bytes

YAML Response

Content-Type: text/yaml

board:
id: c67fda32-...
name: Customer Support
columns:
- name: Backlog
task_count: 1
- name: In Progress
task_count: 0
- name: Review
task_count: 0
- name: Testing
task_count: 0
- name: Done
task_count: 0

Size: 262 bytes -- 79.6% smaller than JSON

Markdown Response

Content-Type: text/markdown

# Board: Customer Support

**Columns**: 5 | **Tasks**: 1

- **Backlog**: 1 tasks
- **In Progress**: 0 tasks
- **Review**: 0 tasks
- **Testing**: 0 tasks
- **Done**: 0 tasks

Size: 220 bytes -- 82.9% smaller than JSON

Format Comparison: Task Detail

JSON Response

{
"id": "task-abc123",
"title": "Fix login timeout issue",
"description": "Users report being logged out after 5 minutes of inactivity",
"status": "in_progress",
"priority": "high",
"assignee": {
"id": "agent-001",
"name": "Support Agent"
},
"column": {
"id": "col-2",
"name": "In Progress"
},
"labels": ["bug", "auth"],
"created_at": "2026-02-21T09:15:00Z",
"updated_at": "2026-02-21T14:30:00Z",
"due_date": "2026-02-25T00:00:00Z"
}

Size: 1,304 bytes

YAML Response

task:
id: task-abc123
title: Fix login timeout issue
status: in_progress
priority: high
assignee: Support Agent
column: In Progress
labels: [bug, auth]
due: 2026-02-25

Size: 249 bytes -- 80.9% smaller

Markdown Response

## Fix login timeout issue

**Status**: In Progress | **Priority**: High
**Assignee**: Support Agent | **Due**: 2026-02-25
**Labels**: bug, auth

Users report being logged out after 5 minutes of inactivity

Size: 186 bytes -- 85.7% smaller

When to Use Each Format

JSON -- Standard Integrations

Use JSON when:

  • Building web or mobile frontends that parse structured data
  • Integrating with third-party systems that expect JSON
  • You need the complete response including all metadata fields (IDs, timestamps, nested objects)
  • Writing automated tests that assert on specific field values

YAML -- AI Agents and Pipelines

Use YAML when:

  • Your AI agent needs structured data it can parse reliably
  • You are chaining API calls in an agent workflow and want to minimize context usage
  • The consumer needs to distinguish between fields programmatically
  • You want a good balance between compactness and parseability

YAML preserves the key-value structure of the data while eliminating JSON syntax overhead. It is ideal for tool-use patterns where the LLM needs to extract specific values.

Markdown -- LLM Prompts and Summaries

Use Markdown when:

  • The response will be injected directly into an LLM prompt as context
  • Maximum token efficiency is the priority
  • The consumer only needs to read and reason about the data, not parse individual fields
  • You are building chat interfaces where responses are displayed to humans

Markdown produces the smallest output by flattening nested structures into headings, bold labels, and lists. It is the most natural format for LLMs to consume as part of a conversation.

Response Headers

The Content-Type header reflects the requested format:

FormatContent-Type Header
JSONapplication/json
YAMLtext/yaml; charset=utf-8
Markdowntext/markdown; charset=utf-8

Error Responses

Error responses are always returned as JSON regardless of the ?format= parameter:

{
"detail": "Board not found"
}

This ensures error handling code does not need to account for multiple formats.

Supported Endpoints

Format negotiation is available on all read endpoints that return resource data:

  • GET /api/v1/boards and GET /api/v1/boards/{id}
  • GET /api/v1/boards/{id}/tasks and GET /api/v1/boards/{id}/tasks/{task_id}
  • GET /api/v1/agents and GET /api/v1/agents/{id}
  • GET /api/v1/clients/me

Write endpoints (POST, PATCH, DELETE) always accept and return JSON.

Further Reading