
In Depth: Speakeasy vs APIMatic

Nolan Sullivan
April 17, 2025

At Speakeasy, we create idiomatic SDKs in the most popular languages. Our generators follow principles that ensure we create SDKs that offer the best developer experience so that you can focus on building your API, and your developer-users can focus on delighting their users.
In this post, we’ll compare TypeScript SDKs created by Speakeasy to those generated by APIMatic.
SDK Generation Targets
At Speakeasy, we believe it is crucial to meet your users where they are by supporting SDKs in languages your users depend on. Anyone who has had to maintain custom SDK code because a vendor doesn’t support their tech stack knows how frustrating this can be.
This table shows the current, as of September 2024, languages and platforms targeted by Speakeasy and APIMatic. These lists will change over time, so check the official documentation for the latest language support.
Language | Speakeasy | APIMatic |
---|---|---|
Python | ✅ | ✅ |
TypeScript | ✅ | ✅ |
Go | ✅ | ✅ (Alpha) |
C# (.NET) | ✅ | ✅ |
PHP | ✅ | ✅ |
Ruby | ✅ | ✅ |
Java | ✅ | ✅ |
Kotlin | ⚠ Java is Kotlin-compatible | ❌ |
Terraform provider | ✅ | ❌ |
Swift | ✅ | ❌ |
Unity | ✅ | ❌ |
Postman Collection | ✅ | ❌ |
We’re always open to expanding our language support, but would only ever do this if we have the in-house experience to create idiomatic, best-in-class SDKs for a given language. Let us know if you would like to suggest a language or platform to support.
SDK Features
The table below compares the current SDK features offered by Speakeasy and APIMatic as of September 2024. Both Speakeasy and APIMatic are under active development, so these features may change over time.
Feature | Speakeasy | APIMatic |
---|---|---|
Union types | ✅ | ✅ |
Discriminated union types | ✅ | ⚠ non-OpenAPI standard |
Server-sent events | ✅ | ❌ |
Retries | ✅ | ✅ |
Pagination | ✅ | ❌ |
Async support | ✅ | ✅ |
Streaming uploads | ✅ | ❌ |
OAuth 2.0 | ✅ | ✅ |
Custom SDK naming | ✅ | ✅ |
Customize SDK structure | ✅ | ❌ |
Custom dependency injection | ✅ | ❌ |
APIMatic lacks advanced SDK customization features, and we couldn’t find any code or documentation related to pagination. These are features Speakeasy’s users rely on.
Platform Features
Speakeasy’s primary interface is an open-source, full-featured, and portable CLI. Developers use our CLI to experiment and iterate locally and to customize their CI/CD workflows.
APIMatic’s CLI depends on Node.js and several packages. This makes it much less portable. In testing, we also found that it does not generate SDKs as reliably as the APIMatic web interface.
Feature | Speakeasy | APIMatic |
---|---|---|
GitHub CI/CD | ✅ | ✅ |
CLI | ✅ | ⚠ |
Web interface | ✅ | ✅ |
Package publishing | ✅ | ✅ |
OpenAPI linting | ✅ | ✅ |
Documentation generation | ✅ | ✅ |
Test generation | ✅ | ✅ |
OpenAPI overlays | ✅ | ❌ |
Change detection | ✅ | ❌ |
Developer portal | ❌ | ✅ |
Enterprise Support
Both Speakeasy and APIMatic offer support for Enterprise customers. This includes features like concierge onboarding, private Slack channels, and enterprise SLAs.
Feature | Speakeasy | APIMatic |
---|---|---|
Concierge onboarding | ✅ | ✅ |
Private Slack channel | ✅ | ✅ |
Enterprise SLAs | ✅ | ✅ |
User issues triage | ✅ | ✅ |
Pricing
Speakeasy offers a free plan, while APIMatic offers a limited free trial.
Plan | Speakeasy | APIMatic |
---|---|---|
Free | 1 free Published SDK, 50 endpoints | Trial only |
Startup | 1 free + $250/mo/SDK, 50 endpoints each | N/A |
Lite: Starter | N/A | $15/mo. 1 API, 10 endpoints, no team members. |
Lite: Basic | N/A | Custom. 1 API, 20 endpoints, 2 team members. |
Business | N/A | Custom. Up to 50 APIs, 100 endpoints each, 15 team members. |
Enterprise | Custom | Custom |
Speakeasy’s free plan is more generous than both Lite plans offered by APIMatic.
Speakeasy vs APIMatic Technical Walkthrough
Dependencies and SBOM (Software Bill of Materials)
Company | Total dependencies | Unmaintained dependencies | Supply chain risks |
---|---|---|---|
Speakeasy | 1 | 0 | 0 |
ApiMatic | 41 | 7 | 4 |
From day one, Speakeasy has prioritized efficiency, and we’ve kept the dependency trees for our generated SDKs as lean as possible. For example, here’s the dependency graph for the Vercel SDK (opens in a new tab), an SDK generated by Speakeasy. It has zero direct dependencies, and one peer dependency (Zod).
By contrast, here’s the dependency graph for the Maxio SDK (opens in a new tab), an SDK generated by APIMatic. It has many dependencies, which in turn have transitive dependencies, leading to a much more bloated SDK that is harder to maintain.
Having more dependencies isn’t only bad in terms of efficiency. Many libraries single or no active maintainer. Many dependencies also have unaddressed critical vulnerabilities (CVs), leaving the upstream SDK vulnerable as well (the Maxio SDK has 4 of these (opens in a new tab)).
Bundle size
Company | Bundle size |
---|---|
Speakeasy | 124.1 kb |
ApiMatic | 358.1 kb |
Dependencies aren’t just a security risk. They also bloat the size of your SDK. Here’s a comparison of the bundle sizes for libraries generated from the same OpenAPI spec by Speakeasy and APIMatic:
That bundle size is a problem if you have customers that need to integrate with your API in runtimes where performance is critical (browser and on the edge).
Type safety
Speakeasy creates SDKs that are type-safe from development to production. As our CEO recently wrote, Type Safe is better than Type Faith.
Speakeasy uses Zod (opens in a new tab) to validate data at runtime. Data sent to the server and data received from the server are validated against Zod definitions in the client.
This provides safer runtime code execution and helps developers who use your SDK to provide early feedback about data entered by their end users. Furthermore, trusting data validation on the client side allows developers more confidence to build optimistic UIs (opens in a new tab) that update as soon as an end user enters data, greatly improving end users’ perception of your API’s speed.
APIMatic will only be validated on the server. This means that the error will only be caught from the client’s perspective after the data is sent to the server, and the server responds with an error message.
As a result, developers using the SDK generated by APIMatic may need to write additional client-side validation code to catch these errors before they are sent to the server.
Discriminated Unions
Our OpenAPI document includes a Book
component with a category
field that can be one of three values: Programming
, Fantasy
, or SciFi
.
This allows us to type the Book
component in requests and responses as specific book types, such as ProgrammingBook
, FantasyBook
, and SciFiBook
.
OpenAPI supports discriminated unions using the discriminator
field in the schema. Here’s an example of a response that returns an array of books of different types:
schema:type: arrayitems:oneOf:- $ref: "#/components/schemas/ProgrammingBook"- $ref: "#/components/schemas/FantasyBook"- $ref: "#/components/schemas/SciFiBook"discriminator:propertyName: categorymapping:Programming: "#/components/schemas/ProgrammingBook"Fantasy: "#/components/schemas/FantasyBook"Sci-fi: "#/components/schemas/SciFiBook"
Let’s see how the SDKs handle this.
Speakeasy generates TypeScript types for each book type, and uses a discriminated union to handle the different book types. This enables developers to use the correct type when working with books of different categories. This pattern could just as easily apply to payment methods or delivery options.
The example below shows how Speakeasy defines the ProgrammingBook
type. It also generates types for FantasyBook
and SciFiBook
.
In this example, you’ll notice that the category
field is optional in the ProgrammingBook
type, but is enforced by Zod validation in the SDK.
/** Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.*/import { Author, Author$ } from "./author";import * as z from "zod";export type ProgrammingBook = {id?: number | undefined;title: string;description: string;/*** Price in USD cents*/price: number;category?: "Programming" | undefined;author: Author;coverImage?: string | undefined;};/** @internal */export namespace ProgrammingBook$ {export const inboundSchema: z.ZodType<ProgrammingBook, z.ZodTypeDef, unknown> = z.object({id: z.number().int().optional(),title: z.string(),description: z.string(),price: z.number().int(),category: z.literal("Programming").optional(),author: Author$.inboundSchema,cover_image: z.string().optional(),}).transform((v) => {return {...(v.id === undefined ? null : { id: v.id }),title: v.title,description: v.description,price: v.price,...(v.category === undefined ? null : { category: v.category }),author: v.author,...(v.cover_image === undefined ? null : { coverImage: v.cover_image }),};});export type Outbound = {id?: number | undefined;title: string;description: string;price: number;category: "Programming";author: Author$.Outbound;cover_image?: string | undefined;};export const outboundSchema: z.ZodType<Outbound, z.ZodTypeDef, ProgrammingBook> = z.object({id: z.number().int().optional(),title: z.string(),description: z.string(),price: z.number().int(),category: z.literal("Programming").default("Programming" as const),author: Author$.outboundSchema,coverImage: z.string().optional(),}).transform((v) => {return {...(v.id === undefined ? null : { id: v.id }),title: v.title,description: v.description,price: v.price,category: v.category,author: v.author,...(v.coverImage === undefined ? null : { cover_image: v.coverImage }),};});}
We can see how Speakeasy generates SDK code to handle the different book types in the response for the getgetAllBooks
operation:
/** Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.*/import * as components from "../components";import * as z from "zod";export type ResponseBody =| (components.ProgrammingBook & { category: "Programming" })| (components.FantasyBook & { category: "Fantasy" })| (components.SciFiBook & { category: "Sci-fi" });export type GetAllBooksResponse = {httpMeta: components.HTTPMetadata;/*** A list of books*/responseBodies?:| Array<| (components.ProgrammingBook & { category: "Programming" })| (components.FantasyBook & { category: "Fantasy" })| (components.SciFiBook & { category: "Sci-fi" })>| undefined;};// ...
Note how the array elements in responseBodies
are typed according to the book category.
This may seem like a trivial example, but it illustrates how Speakeasy generates types that are more specific and easier to work with than the types generated by APIMatic. This could, for instance, help developers correctly handle different book types in their applications.
APIMatic does not generate types for discriminated unions, and developers must manually handle the different book types in the response.
Here is the equivalent type definition generated by APIMatic:
/*** Bookstore APILib** This file was automatically generated by APIMATIC v3.0 ( https://www.apimatic.io ).*/// ...import { CategoryEnum, categoryEnumSchema } from './categoryEnum';// ...export interface ProgrammingBook {id?: number;title: string;description: string;/** Price in USD cents */price: number;category: CategoryEnum;author: Author2;coverImage?: string;}// ...
Following the CategoryEnum
import:
/*** Bookstore APILib** This file was automatically generated by APIMATIC v3.0 ( https://www.apimatic.io ).*/// .../*** Enum for CategoryEnum*/export enum CategoryEnum {Scifi = 'Sci-fi',Fantasy = 'Fantasy',Programming = 'Programming',}// ...
Discriminating between different book types in the response is left to users.
Speakeasy Compared to Open-Source Generators
If you are interested in seeing how Speakeasy stacks up against other SDK generation tools, check out our post.