Learn A2A - Content & Structured Output
Series/Learn A2A/Episode 8
Episode 8 of 23

Learn A2A - Content & Structured Output

Dive into the Part types for inter-agent content: text, files with dataURI and mimeType, up to structured data based on JSON schema. Including a case study of structured lead transfer between agents without free parsing.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Introduction

In episode 7 we saw how status, messages, and artifacts flow through streaming and push notifications. But all those examples still used plain text — an agent sends sentences, another agent receives sentences. In the real world, agents often need to exchange something far more structured: datasets, PDF documents, or lead records that must be read without misinterpretation. This episode covers the forms of content agents can send to each other.

This episode's roadmap: we dissect the anatomy of Part as the smallest content unit, then each of its types one by one — TextPart, FilePart, and DataPart — ending with a case study of structured data transfer between agents, complete with practice that avoids free parsing.

Anatomy of Part: The Smallest Content Unit

In episode 4 we learned that Message and Artifact both contain a collection of Part. Part is the smallest content unit an agent can carry — the equivalent of a "row" in a table. Its basic structure is simple: each part carries a kind that marks its type, followed by data specific to that type.

A portion of a Message
{
  "role": "user",
  "parts": [
    { "kind": "text", "text": "Analisis tren penjualan", "metadata": { "prioritas": "tinggi" } },
    { "kind": "file", "file": { "name": "data-penjualan.csv", "mimeType": "text/csv", "uri": "https://storage.example.com/sales.csv" } },
    { "kind": "data", "data": { "periode": "Q3-2026", "region": "Jawa Timur" } }
  ]
}

Because Message and Artifact accept a list of parts, a single message can hold everything at once: instruction text, supporting files, and structured data. The receiving agent reads each part according to its kind. The three main kind values we'll dissect: text, file, and data.

Text: TextPart

TextPart is the simplest and most commonly used type — we've been sending it since episode 6. Its structure has only two fields: text holds the content, and optional metadata holds extra labels like priority or language.

A plain TextPart and one with metadata
{ "kind": "text", "text": "Ringkas artikel ini dalam tiga poin" }
TextPart with metadata
{ "kind": "text", "text": "Analisis tren penjualan", "metadata": { "prioritas": "tinggi", "bahasa": "id" } }

As simple as it is, TextPart has a limit you should be aware of: text carries no structure. Numbers, dates, and statuses inside it must be re-parsed by the receiver — that's its weakness for structured data transfer.

File: FilePart

For non-text content — PDFs, images, spreadsheets, CSVs — use FilePart. Its structure carries name for the file name and mimeType for the media type. The content itself can be provided in two ways: inline as a dataUri (base64-encoded data), or by reference through a uri to a downloadable URL:

FilePart inline with dataURI
{
  "kind": "file",
  "file": {
    "name": "laporan-q2.pdf",
    "mimeType": "application/pdf",
    "dataUri": "data:application/pdf;base64,JVBERi0xLjQK..."
  }
}
FilePart by reference with URI
{
  "kind": "file",
  "file": {
    "name": "dataset-customer.csv",
    "mimeType": "text/csv",
    "uri": "https://storage.example.com/datasets/customer-2026.csv"
  }
}

dataUri suits small files that must be sent all at once; uri is more bandwidth-efficient for large files because the receiving agent simply downloads them. An important note: the receiving agent must use mimeType to choose how to process — don't guess from the file extension, which can be misleading.

Structured Data: DataPart

This is the main weapon for structured content. DataPart carries a data field containing any JSON object. No text parsing, no free interpretation — the structure is available directly. To wrap it in a clear contract, the A2A specification connects DataPart with JSON Schema through the input and output declarations on skills in the Agent Card:

DataPart containing a structured lead
{
  "kind": "data",
  "data": {
    "lead_id": "L-1024",
    "nama_perusahaan": "PT Nusantara Maju",
    "industri": "logistik",
    "estimasi_nilai": 250000000,
    "kontak": { "email": "sales@nusantara.example", "telepon": "+62 21 5555 0101" }
  }
}
Skill with a JSON schema declaration
{
  "id": "analisis_lead",
  "name": "Analisis Lead",
  "description": "Menerima data lead dan mengembalikan skor serta rekomendasi.",
  "inputModes": ["application/json"],
  "outputModes": ["application/json"],
  "inputSchema": {
    "$ref": "https://schema.internal.example.com/lead-input.json"
  }
}

With inputModes: ["application/json"] and the inputSchema reference, the client knows exactly the expected data shape — and the agent producing the data can be validated against the same schema. This makes DataPart the bridge for machine-to-machine scenarios without ambiguity.

Case Study: Lead Transfer Between Agents

Let's tie it all together. There are two agents: a CRM agent that finds prospects, and a sales agent that scores them. The CRM agent sends its result via DataPart, and the sales agent reads kind: "data" to access the fields directly:

{
  "kind": "data",
  "data": {
    "lead_id": "L-1024",
    "nama_perusahaan": "PT Nusantara Maju",
    "industri": "logistik",
    "estimasi_nilai": 250000000,
    "sumber": "pameran-logistics-2026"
  }
}

Note the flow. The CRM agent doesn't construct sentences to be parsed — it composes a JSON object. The sales agent looks for a part of kind data, reads lead_id and estimasi_nilai as fields, and replies with a new DataPart containing the score. The entire chain runs without regex, without string parsing, without format assumptions.

Success

The power of this pattern shows when many agents are involved. The same lead can be processed by sales scoring, then forwarded as a DataPart to a CRM agent, then to a marketing agent — each hop simply adds fields to the JSON object without worrying that the text format will change mid-way.

Best Practices: Don't Parse Freely

Armed with the three Part types, here are practices that keep data exchange healthy in production:

  • Use DataPart for data, not text. Anything that has structure — leads, products, orders, configuration — send it as data, not as a sentence summary.
  • Declare schemas on skills. Fill in inputSchema and outputSchema so clients can build and validate payloads correctly.
  • Honor mimeType and schema versions. Large files via uri; schemas get versions (v1, v2) and are stored at stable URLs so old agents don't break when schemas change.
  • Be strict with invalid data. If the structure doesn't match the schema, ask for input again via the input-required state rather than guessing or silently filling in defaults.
  • Avoid implicit expectations. Don't read fields that aren't declared in the schema; make the schema the only contract.

Warning

Never send credentials and sensitive data inline as a dataUri in task payloads. Internal files with restricted access are safer referenced through a uri downloaded with authentication, rather than embedded base64 into a task history that could end up in logs.

Conclusion

Episode 8 completes the A2A content vocabulary: TextPart for text, FilePart for files with dataUri or uri plus mimeType, and DataPart for structured data based on JSON schema. Through the lead transfer case study, you saw how agents build and read structures directly — without fragile free parsing. The key is to make the schema a contract, not just documentation.

Here's the core takeaway:

  • Part is the smallest content unit, grouped into Message and Artifact.
  • TextPart for text; FilePart for inline (dataUri) or referenced (uri) files with mimeType.
  • DataPart carries a structured JSON object read directly as fields, not parsed.
  • Declaring inputSchema/outputSchema on skills binds data exchange to a JSON schema contract.
  • Structured data between agents eliminates free parsing and makes multi-agent pipelines predictable.

Once content can be structured and safe, the next question that surfaces in production is: who is allowed to call our agent? In episode 9 we discuss Authentication & Security — OAuth 2.1, API key, and JWT flows on the authentication field in the Agent Card, plus signed agent cards for verifying identity and capability integrity. See you there!

Learn A2A - Content & Structured Output | Learn A2A