Response formats

Every endpoint returns JSON by default. The same data is also available as XML through standard HTTP content negotiation — useful when your application already speaks XML. The response body is identical in shape; only the serialization changes.

Asking for XML

Two ways, in priority order:

  • Accept: application/xml — the standard mechanism.
  • ?format=xml — an explicit query-param override, handy in a browser or a quick curl. ?format=json forces JSON even when Accept asks for XML.

With no Accept header, Accept: */*, or Accept: application/json, you get JSON exactly as before — existing integrations are unaffected.

bash
# Default — JSON curl -H "Authorization: Bearer leg_..." \ https://legalize.dev/api/v1/es/laws/BOE-A-1978-31229 # XML via Accept header curl -H "Authorization: Bearer leg_..." \ -H "Accept: application/xml" \ https://legalize.dev/api/v1/es/laws/BOE-A-1978-31229 # XML via query param (no custom header needed) curl -H "Authorization: Bearer leg_..." \ "https://legalize.dev/api/v1/es/laws/BOE-A-1978-31229?format=xml"

XML shape

The serializer is small and predictable. The document root is <response>; object keys become elements; arrays become repeated <item> elements wrapped in the parent key. Text is XML-escaped.

xml
<?xml version="1.0" encoding="UTF-8"?> <response> <country>es</country> <total>8677</total> <page>1</page> <per_page>50</per_page> <results> <item> <id>BOE-A-1978-31229</id> <title>Constitución Española</title> </item> <item> ... </item> </results> </response>

From the SDKs

The typed resource methods (laws.retrieve, …) always return JSON-parsed models. To get the raw XML for any endpoint, use the low-level request_raw primitive — it sets the format and hands you the body untouched.

# Raw XML string… res = client.request_raw("GET", "/api/v1/es/laws/BOE-A-1978-31229") xml = res.text # content_type == "application/xml; charset=utf-8" # …or parsed into an ElementTree on the spot. root = res.xml() title = root.find("title").text
const res = await client.requestRaw("GET", "/api/v1/es/laws/BOE-A-1978-31229"); const xml = res.text; // res.contentType === "application/xml; charset=utf-8"
res, err := client.RequestRaw(ctx, "GET", "/api/v1/es/laws/BOE-A-1978-31229", nil) if err != nil { return err } xml := res.Text // res.ContentType, res.StatusCode also available

request_raw defaults to format="xml", so the examples above already negotiate XML. Pass format="json" to fetch a raw JSON body the same way.

Errors

Error responses honor the same negotiation: if you asked for XML, a 404 or 401 comes back as XML with the same envelope (error, message, detail).

xml
<?xml version="1.0" encoding="UTF-8"?> <response> <error>http_404</error> <message>Law not found: BOE-A-9999-99999</message> </response>
Caching. XML and JSON responses carry Vary: Accept, so any cache or CDN keeps the two representations of a URL separate and never serves the wrong one.