Tech spotlight: How we re-launched our API docs
Tech spotlight: How we re-launched our API docs
copy gray icon

Tech spotlight: How we re-launched our API docs

March 25, 2021

I'm Aaron Pelz, an Engineering Manager at Pinwheel. I love building elegant APIs, using threads in Slack, and coming up with bad names for microservices. One thing I don't love is updating documentation, especially at a fast growing company where we're adding new functionality constantly! Following the launch of our new docs, I wanted to share the story of the technical changes behind the scenes, and how our engineering team made it happen while removing a lot of toil in the process. If you find keeping your docs up to date is cumbersome or error prone, or just want a peek under the hood, I hope you'll find this post helpful.

When Pinwheel first launched our Direct Deposit product, we were building fast. To get customers up and running quickly, we set up a site to host our API documentation powered by Docz and wrote a number of descriptive implementation guides that combined technical explanations with reference specs detailing our API's full behavior. With only a handful of people on the team, engineers deployed a feature then pushed out updates to the appropriate user guides. It was easy enough at first, but as the team and product grew, so did the number of manual edits needed every week. Engineers notoriously dislike process that doesn't scale, and pretty soon we found ourselves looking for a remedy.

The Fastest API in the West

Around the time of our public launch, we also embarked on a major technical upgrade: switching the framework that powered our public API from Express.js to FastAPI, a modern Python framework built on a speedy ASGI server. In addition to performance (a topic for another blog post), FastAPI comes with its own OpenAPI 3 specification generator. OpenAPI 3 is a popular specification that can describe REST APIs like ours, and putting our spec in the wild would make it easier for other developers to understand, test, and integrate with our product. And best of all, FastAPI could introspect on the endpoints we defined in the code itself, generating the entire spec for us—paths, schemas, and tags—out of the box. Using the generator instead of forcing engineers to manually update the docs was a no-brainer.

Paring it Down

After finalizing the swap to FastAPI internally, we eagerly embarked on the journey to wrangle the autogenerated OpenAPI spec into something we could share with the public, and quickly ran into some problems. To start, we have a number of private, internal endpoints that live in the same codebase as our public API. And like many tech companies, we are constantly deploying new versions of code, in testing and production environments, that include beta features not ready for public consumption. That presents a problem when everything is added to the docs by default! We needed a way to conditionally display and modify what FastAPI spat out.

To solve this, we decided to implement custom schema modifications that were based on environment variables present in our various development environments. Doing so let us see private and public endpoints together on our internal tools while keeping them secret from the public until we were ready to launch. The documentation we shared externally would be generated in the same production environment where users interact with our API.

import uuidfrom fastapi import APIRouter, Requestfrom pinwheel import settingsfrom pinwheel.models import PrivateModelfrom pinwheel.managers import get_private_modelrouter = APIRouter()@router.get(    "/{object_id}",    response_model=PrivateModel,    include_in_schema=settings.ENV == "staging")def private_route(    request: Request,    object_id: uuid.UUID):    return get_private_model(object_id)

view rawpinwheel.routes.py hosted with ❤ by GitHub


This was easy enough for entire routes, but modifying individual fields was an added layer of complexity. What if we needed to add a beta field to a response and keep it secret? Fortunately, FastAPI uses Pydantic under the hood to build schemas for requests and responses, which let us define reusable models in our code. When responses exit our servers, Pydantic objects are converted to Python dictionaries, then serialized to JSON. To enforce our API conventions programmatically while allowing environment-specific behavior, we built an abstract model class that all public models inherit from. Now we could pick and choose which fields were omitted in our production environment.

from abc import ABCfrom typing import List, Dict, Type, Anyfrom pydantic import BaseModel, Fieldfrom pinwheel import settingsclass PinwheelPublicBaseModel(BaseModel, ABC):    _hide_fields_from_public_docs: List[str]    class Config:        @staticmethod        def schema_extra(            schema: Dict[str, Any], model: Type["PinwheelPublicBaseModel"]        ) -> None:            """            Custom JSON schema modifications for Pydantic models.            https://pydantic-docs.helpmanual.io/usage/schema/            """            if settings.ENV == "production":                properties = schema.get("properties", {})                for field in model._hide_fields_from_public_docs:                    properties.pop(field, None)class PublicModel(PinwheelPublicBaseModel):    foo: str     bar: int    secret_beta_feature: str    _hide_fields_from_public_docs = ["secret_beta_feature"]

view rawpinwheel.models.py hosted with ❤ by GitHub


Building it Up

Now that we were exclusively generating docs ready for the public in production, we wanted to enrich the OpenAPI spec. FastAPI has a hook to write custom OpenAPI generation code, and combining that with our custom models, we could add some extra flair. For example, to ship response examples along with every successful API response, we added an hook to iterate over all relevant endpoints and populate them with examples generated programatically.

import typesfrom fastapi import FastAPIfrom pinwheel.openapi import custom_openapiapp = FastAPI()app.openapi = types.MethodType(custom_openapi, app)

view rawpinwheel.app.py hosted with ❤ by GitHub

from typing import Dictfrom fastapi import FastAPIfrom fastapi.openapi.utils import get_openapifrom pinwheel.models import PinwheelPublicBaseModeldef add_examples_to_schema(openapi_schema: Dict) -> None:    for path, verbs in openapi_schema["paths"].items():        for verb, request in verbs.items():            success_response = request["responses"]["200"]["content"]["application/json"]            response_model_ref = success_response["schema"]["$ref"]            success_response["examples"] = PinwheelPublicBaseModel.generate_examples(                response_model_ref            )def custom_openapi(app: FastAPI, *args, **kwargs) -> Dict:    """    A custom wrapper around FastAPI's OpenAPI generator.     """    openapi_schema = get_openapi(        title="Pinwheel",        description="Pinwheel is the API for Payroll",        version="1.0.0",        routes=app.routes    )    add_examples_to_schema(openapi_schema)    app.openapi_schema = openapi_schema    return app.openapi_schema

view rawpinwheel.openapi.py hosted with ❤ by GitHub


This approach also made it easy to define an example in code a single time and reuse it throughout the docs. Repeating the tactic, we can format and enrich every endpoint with tags, additional formatting, and extra descriptions, making the spec more informative and easier to digest. And with everything generated programmatically, we could also write unit tests for the generated spec to ensure it was both fully featured and convention compliant.

Enter Stoplight

Now that we had our fresh, autogenerated API reference, we needed to merge it with our existing documentation to show it side by side with our product and user guides. At the same time, we brought on some amazing product and sales people who wanted to contribute to the docs without needing to check in changes to our Github repo. To get the best of both worlds, we launched a refresh of our docs with a tool called Stoplight, which displays guides side by side with endpoints directly from an OpenAPI spec. Engineers can push changes programmatically while anyone else can edit our guides directly on Stoplight's website. Stoplight also ships with a number of mocking, testing, and code generation tools to help developers test out and build on our product.

Stitching it all together, our docs have come a long way from the early days of manual updates. Now, a fresh copy of our API reference is generated whenever we deploy changes to our product, our commercial team can use the documentation as a foundation for sales conversations, and it's easier than ever to integrate with Pinwheel. FastAPI has lived up to its name, and months later we're building faster than ever.

If you never want to remember to write API reference docs again, join us — we're hiring!

Always stay up to date

View our Privacy Policy   ➔
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Up next

The digital gap threatening credit unions—and how to close it

The digital gap threatening credit unions—and how to close it

Read more  ➔
Are Gen Z and Millennials your most valuable—and most underserved—banking customers?

Are Gen Z and Millennials your most valuable—and most underserved—banking customers?

Read more  ➔
Pinwheel Helping Power Robinhood Banking Deposits

Pinwheel Helping Power Robinhood Banking Deposits

Read more  ➔
Visa Launches Enhanced Subscription Manager, Giving Consumers Greater Control Over Recurring Payments

Visa Launches Enhanced Subscription Manager, Giving Consumers Greater Control Over Recurring Payments

Read more  ➔
OnePay Partners with Pinwheel

OnePay Partners with Pinwheel

Read more  ➔
Leighanne Levensaler joins Pinwheel as strategic advisor

Leighanne Levensaler joins Pinwheel as strategic advisor

Read more  ➔
River launches direct deposit powered by Pinwheel Deposit Switch

River launches direct deposit powered by Pinwheel Deposit Switch

Read more  ➔
KYC’s Killer App

KYC’s Killer App

Read more  ➔
J.D. Power confirms ROI of bank account "Soft Switching"

J.D. Power confirms ROI of bank account "Soft Switching"

Read more  ➔
Pinwheel welcomes Don Weinstein as an advisor

Pinwheel welcomes Don Weinstein as an advisor

Read more  ➔
Future of account onboarding

Future of account onboarding

Read more  ➔
How we help lenders unlock the value of Pay by Paycheck

How we help lenders unlock the value of Pay by Paycheck

Read more  ➔
Pay By Paycheck: The next big thing in lending

Pay By Paycheck: The next big thing in lending

Read more  ➔
A new chapter for Pinwheel

A new chapter for Pinwheel

Read more  ➔
Hey - remember us from tax season?

Hey - remember us from tax season?

Read more  ➔
Narmi x Pinwheel expand partnership with the Switch Kit

Narmi x Pinwheel expand partnership with the Switch Kit

Read more  ➔
Winning the war for primacy with digital innovation

Winning the war for primacy with digital innovation

Read more  ➔
Did the CFPB Eat Your Homework?

Did the CFPB Eat Your Homework?

Read more  ➔
Achieving loyalty with a differentiated digital experience

Achieving loyalty with a differentiated digital experience

Read more  ➔
​Revolutionizing digital banking: How Bill Manager drives engagement and growth

​Revolutionizing digital banking: How Bill Manager drives engagement and growth

Read more  ➔
Pinwheel expands PreMatch coverage to 45M Americans with addition of Paychex partnership

Pinwheel expands PreMatch coverage to 45M Americans with addition of Paychex partnership

Read more  ➔
Pinwheel Pulse: Q1 2025

Pinwheel Pulse: Q1 2025

Read more  ➔
Citadel Direct Deposit Manager is powered by Pinwheel

Citadel Direct Deposit Manager is powered by Pinwheel

Read more  ➔
Security Bank of Kansas City upgrades account onboarding with Pinwheel

Security Bank of Kansas City upgrades account onboarding with Pinwheel

Read more  ➔
Pinwheel partners with MoneyLion to power Direct Deposit Switching

Pinwheel partners with MoneyLion to power Direct Deposit Switching

Read more  ➔
Consumer Banking Sentiment 2025

Consumer Banking Sentiment 2025

Read more  ➔
Q&A with Meriwest Head of Digital Strategy, Gene Fichtenholz

Q&A with Meriwest Head of Digital Strategy, Gene Fichtenholz

Read more  ➔
Roster Mentality & Retail Banking

Roster Mentality & Retail Banking

Read more  ➔
Achieve primacy day one

Achieve primacy day one

Read more  ➔
Pinwheel Pulse: 2024 Year in Review

Pinwheel Pulse: 2024 Year in Review

Read more  ➔
Why credit unions have a neighborhood advantage

Why credit unions have a neighborhood advantage

Read more  ➔
The Product Pulse

The Product Pulse

Read more  ➔
Introducing Bill Manager

Introducing Bill Manager

Read more  ➔
PreMatch results are in

PreMatch results are in

Read more  ➔
How we achieve the industry’s best conversion rates

How we achieve the industry’s best conversion rates

Read more  ➔
Automated direct deposit is powering the next generation of growth for credit unions

Automated direct deposit is powering the next generation of growth for credit unions

Read more  ➔
Nassau Financial Credit Union Selects Pinwheel As Direct Deposit Switch Partner

Nassau Financial Credit Union Selects Pinwheel As Direct Deposit Switch Partner

Read more  ➔
SafeLink expands access to frictionless experiences

SafeLink expands access to frictionless experiences

Read more  ➔
Industry leaders talk consumer bank switching behaviors

Industry leaders talk consumer bank switching behaviors

Read more  ➔
The branch of the future

The branch of the future

Read more  ➔
Giving credit where it’s due

Giving credit where it’s due

Read more  ➔
Trust and Verify

Trust and Verify

Read more  ➔
Citizens & Pinwheel talk primacy

Citizens & Pinwheel talk primacy

Read more  ➔
Be the Amazon of banks  

Be the Amazon of banks  

Read more  ➔
Enhancing digital trust: Inside Pinwheel's commitment to security

Enhancing digital trust: Inside Pinwheel's commitment to security

Read more  ➔
Who’s making money moves in 2024?

Who’s making money moves in 2024?

Read more  ➔
Consumer bank switching behavior demystified

Consumer bank switching behavior demystified

Read more  ➔
The metrics you care about the most are now available in real-time

The metrics you care about the most are now available in real-time

Read more  ➔
New Jack Henry partnership makes it easier for community banks to take advantage of Pinwheel

New Jack Henry partnership makes it easier for community banks to take advantage of Pinwheel

Read more  ➔
 Pinwheel's CMO discusses bank competition for primacy in 2024

Pinwheel's CMO discusses bank competition for primacy in 2024

Read more  ➔
Introducing the next generation of Automated Direct Deposit Switching

Introducing the next generation of Automated Direct Deposit Switching

Read more  ➔
Fraud Fighers Chapter 1: Know Your Fraudster

Fraud Fighers Chapter 1: Know Your Fraudster

Read more  ➔
Know Your Fraudster Q&A with Robert Reynolds

Know Your Fraudster Q&A with Robert Reynolds

Read more  ➔
This is how banks close the loop with branch guests: Introducing Pinwheel Smart Branch

This is how banks close the loop with branch guests: Introducing Pinwheel Smart Branch

Read more  ➔
Introducing Pinwheel Deposit Switch 2.0, a revolutionary upgrade that maximizes coverage and conversion for every US worker

Introducing Pinwheel Deposit Switch 2.0, a revolutionary upgrade that maximizes coverage and conversion for every US worker

Read more  ➔
Key factors to consider before implementing a payroll connectivity API

Key factors to consider before implementing a payroll connectivity API

Read more  ➔
Enhance credit line management with income data

Enhance credit line management with income data

Read more  ➔
See your customers’ earnings weeks into the future with projected earnings

See your customers’ earnings weeks into the future with projected earnings

Read more  ➔
How to reduce default risk with consumer-permissioned data

How to reduce default risk with consumer-permissioned data

Read more  ➔
Digital lending technologies and trends that are shaping the industry

Digital lending technologies and trends that are shaping the industry

Read more  ➔
4 technologies that improve fraud detection in banking

4 technologies that improve fraud detection in banking

Read more  ➔
Why automated income verification is a must-have feature for lenders

Why automated income verification is a must-have feature for lenders

Read more  ➔
December product release: 10% increase in conversion, enhanced security and access to pay frequency data

December product release: 10% increase in conversion, enhanced security and access to pay frequency data

Read more  ➔
A conversation with our Chief Information Security Officer

A conversation with our Chief Information Security Officer

Read more  ➔
Former CFPB Deputy Director Raj Date Joins Pinwheel as an Advisor

Former CFPB Deputy Director Raj Date Joins Pinwheel as an Advisor

Read more  ➔
Cash flow underwriting: Benefits & how to access cash flow data

Cash flow underwriting: Benefits & how to access cash flow data

Read more  ➔
Why banks need a payroll connectivity API that prioritizes information security

Why banks need a payroll connectivity API that prioritizes information security

Read more  ➔
How alternative credit data can benefit lenders

How alternative credit data can benefit lenders

Read more  ➔
Tech Spotlight: Implementing your first feature flag

Tech Spotlight: Implementing your first feature flag

Read more  ➔
Pinwheel Welcomes New Advisor, Ethan Yeh, to Advance Pinwheel’s Data Science Strategy

Pinwheel Welcomes New Advisor, Ethan Yeh, to Advance Pinwheel’s Data Science Strategy

Read more  ➔
Tech spotlight: Securing access control across internal services

Tech spotlight: Securing access control across internal services

Read more  ➔
The anatomy and potential of payroll data: Transforming complex data into insights

The anatomy and potential of payroll data: Transforming complex data into insights

Read more  ➔
Beyond the credit score: Propelling consumer finance into the future with income data

Beyond the credit score: Propelling consumer finance into the future with income data

Read more  ➔
Ayokunle (Ayo) Omojola joins Pinwheel’s Board of Directors

Ayokunle (Ayo) Omojola joins Pinwheel’s Board of Directors

Read more  ➔
Conquering conversion: Engineering practices developed to help customers

Conquering conversion: Engineering practices developed to help customers

Read more  ➔
Driving Customer Delight: From implementation and beyond

Driving Customer Delight: From implementation and beyond

Read more  ➔
Pinwheel Supports Open Finance Data Security Standard

Pinwheel Supports Open Finance Data Security Standard

Read more  ➔
How we design Pinwheel to solve real customer problems

How we design Pinwheel to solve real customer problems

Read more  ➔
What is consumer-permissioned data and what are its benefits?

What is consumer-permissioned data and what are its benefits?

Read more  ➔
How payroll data connectivity can help financial service providers in tumultuous market conditions

How payroll data connectivity can help financial service providers in tumultuous market conditions

Read more  ➔
Pinwheel now supports document uploads to supplement payroll data

Pinwheel now supports document uploads to supplement payroll data

Read more  ➔
Brian Karimi-Pashaki joins Pinwheel as Partnerships Lead

Brian Karimi-Pashaki joins Pinwheel as Partnerships Lead

Read more  ➔
Optimizing for conversion with smarter employer mappings

Optimizing for conversion with smarter employer mappings

Read more  ➔
What are super apps and how will they impact financial services?

What are super apps and how will they impact financial services?

Read more  ➔
Increase conversions and maximize share of wallet with Pinwheel's new UX update

Increase conversions and maximize share of wallet with Pinwheel's new UX update

Read more  ➔
Pinwheel announces support for taxes

Pinwheel announces support for taxes

Read more  ➔
Ryan Nier Joins Pinwheel as the Company’s first General Counsel

Ryan Nier Joins Pinwheel as the Company’s first General Counsel

Read more  ➔
The future of enabling earned wage access

The future of enabling earned wage access

Read more  ➔
Deliver earned wage access faster with Pinwheel Earnings Stream

Deliver earned wage access faster with Pinwheel Earnings Stream

Read more  ➔
Digital transformation in banking in 2022: What it means, trends & examples

Digital transformation in banking in 2022: What it means, trends & examples

Read more  ➔
June product release: Expanded connectivity to employers, a custom experience with Link API and more

June product release: Expanded connectivity to employers, a custom experience with Link API and more

Read more  ➔
Pinwheelie Spotlight: LaRena Iocco, Software Engineer

Pinwheelie Spotlight: LaRena Iocco, Software Engineer

Read more  ➔
Build fully custom experiences with Pinwheel’s Link API

Build fully custom experiences with Pinwheel’s Link API

Read more  ➔
Pinwheel expands connectivity to 1.5M employers

Pinwheel expands connectivity to 1.5M employers

Read more  ➔
Robert Reynolds joins Pinwheel as Head of Product

Robert Reynolds joins Pinwheel as Head of Product

Read more  ➔
Pinwheel obtains highest security certification in the industry

Pinwheel obtains highest security certification in the industry

Read more  ➔
Lauren Crossett becomes Pinwheel’s first Chief Revenue Officer

Lauren Crossett becomes Pinwheel’s first Chief Revenue Officer

Read more  ➔
Everything you should know about the role of APIs in banking

Everything you should know about the role of APIs in banking

Read more  ➔
Open finance: What is it and how does it impact financial services?

Open finance: What is it and how does it impact financial services?

Read more  ➔
How automated direct deposit switching benefits traditional banks

How automated direct deposit switching benefits traditional banks

Read more  ➔