## Non-JSON Responses

`apiRequest()` decodes responses as JSON by default. For endpoints that return non-JSON payloads, pass `responseType`:

- `"binary"` for PDFs and other byte payloads. The result is a `Uint8Array`
- `"text"` for XML, CSV, HTML, and other decoded strings

With `responseType: "text"` or `responseType: "binary"` the response schema may be omitted. Text returns the raw string typed `unknown`. Binary returns a `Uint8Array`:

```typescript
const xml = await ctx.integrations.legacyApi.apiRequest({
  method: "GET",
  path: "/report.xml",
  responseType: "text",
});
// xml is the raw XML string (typed unknown)

const pdf = await ctx.integrations.legacyApi.apiRequest({
  method: "GET",
  path: "/file.pdf",
  responseType: "binary",
});
// pdf is a Uint8Array
```

To validate after decoding, pass a schema that matches the decoded value:

```typescript
const xml = await ctx.integrations.legacyApi.apiRequest(
  { method: "GET", path: "/report.xml", responseType: "text" },
  { response: z.string() },
);
// xml is typed string

const pdf = await ctx.integrations.legacyApi.apiRequest(
  { method: "GET", path: "/file.pdf", responseType: "binary" },
  { response: z.instanceof(Uint8Array) },
);
// pdf is typed Uint8Array
```

Convert binary data to a JSON-safe representation before returning it from an SDK API:

```typescript
return {
  contentBase64: Buffer.from(pdf).toString("base64"),
  filename: "file.pdf",
};
```

JSON responses (the default) always require a response schema. Omitting the schema is only allowed together with an explicit `responseType: "text"` or `responseType: "binary"`, so unvalidated JSON is not representable.
