Guide
API Examples & Best Practices
Table of Contents
An API (application programming interface) is a collection of rules, protocols, and definitions that enable software programs to interact with one another programmatically. APIs serve as bridges between systems and allow them to exchange data and functionality without human intervention.
While APIs are ubiquitous in modern software, developing them comes with various challenges. Developers often face issues balancing performance and scalability, maintaining backward compatibility during updates, ensuring secure authentication, and designing distinct interfaces that do not limit adaptability.
In this article, we will explore various topologies of APIs. We will dive into different API examples, API design considerations, and provide concrete recommendations for how to create APIs that are secure, performant, and meet modern business requirements.
Summary of key API examples and concepts
The table below summarizes the primary API concepts we will explore in this article.
Concept | Description |
---|---|
Types of APIs | APIs can be categorized by access levels:
|
API paradigms | Different API styles are used for specific use cases depending on their performance and flexibility:
|
Use cases of APIs | API implementations vary across use cases, from social media integrations like Facebook to service APIs like Twilio and AWS SES for notifications and email delivery. E-commerce platforms rely on payment gateway APIs for secure transactions, while private APIs often use gRPC to streamline internal service communication with high performance and low latency. |
The importance of standardized API design | APIs should adhere to established standards to improve usability and ensure clarity regarding their purpose. API design patterns assist in designing interfaces that effectively communicate the origin and purpose of data. |
Types of APIs
APIs come in different forms, each designed to serve different purposes, audiences, and use cases. Understanding these categories helps developers and organizations choose the right tools for their needs, whether they’re building apps for the general public, collaborating with partners, or streamlining internal operations.
This section explores three key types of APIs:
- Public APIs that are openly accessible to developers
- Private APIs used in private tools for internal systems
- Partner APIs that are restricted to authorized collaborators
We will see how each type works, discuss its benefits, and provide real-world examples to illustrate practical applications.
Public APIs
Public APIs, often called external or open APIs, are interfaces provided by companies, organizations, or platforms that allow developers and the general public to access specific data or functionalities. These APIs typically include detailed and well-structured documentation, making it easier for developers to begin using them promptly.
For example, this OpenWeather’s API allows developers to fetch real-time data about the current weather in London:
curl --request GET \
--url "https://api.openweathermap.org/data/2.5/weather?q=London&appid=YOUR_API_KEY"
The API returns a JSON object with details like temperature, humidity, and weather conditions:
{
"coord": { "lon": -0.1257, "lat": 51.5085 },
"weather": [
{ "main": "Overcast", "description": "Clouds", "icon": "01d" }
],
"main": {
"temp": 282.55,
"feels_like": 281.86,
"temp_min": 280.37,
"temp_max": 284.26,
"humidity": 81
},
"wind": { "speed": 1.03 },
"sys": { "country": "GB" },
"name": "London"
}
Private API
Private APIs exist behind the scenes to streamline internal communications and operations within a company. For example, a retail company may use an internal inventory management API to allow store managers to check stock levels. In this scenario, the API fetches real-time data from the warehouse database:
curl -X GET "https://internal-api.company.com/inventory/items/12345" \
-H "Authorization: Bearer internal_access_token"
And the API would return a response with the requested data:
{
"itemId": "12345",
"name": "Wireless Headphones",
"stockLevel": 42,
"location": "Warehouse A"
}
Private APIs are typically used to facilitate communication between internal services, improve automation, and enhance security by limiting access to only authorized internal systems. Because security is a primary concern for many organizations, private APIs often utilize authorization mechanisms like JSON Web Tokens (JWTs) or OAuth 2.0. In addition, they may implement IP whitelisting and role-based access control (RBAC) to ensure only trusted systems can communicate.
Partner APIs
Partner APIs occupy a unique middle ground between public and private APIs. Unlike public APIs, which are openly accessible, partner APIs are shared exclusively with specific business partners or organizations. This restricted access enables secure and controlled integrations, making them ideal for B2B (business-to-business) collaborations.
For example, Skyscanner’s Travel API is a partner API that allows authorized partners to integrate flight search and booking functionalities into their applications. Skyscanner implements proprietary security and access control mechanisms to ensure that only approved entities can access its features.
The following example shows how to use the Skyscanner API to fetch live prices bookable flights from New York (JFK) to Los Angeles (LAX) on a specific date:
curl --request POST \
'https://partners.api.skyscanner.net/apiservices/v3/flights/live/search/create' \
--header 'x-api-key: your-api-key' \
--header 'Content-Type: application/json' \
--data '{
"query": {
"market": "US",
"locale": "en-US",
"currency": "USD",
"queryLegs": [
{
"originPlace": {
"queryPlace": { "iata": "JFK" }
},
"destinationPlace": {
"queryPlace": { "iata": "LAX" }
},
"date": {
"year": 2023,
"month": 12,
"day": 1
}
}
]
}
}'
The Skyscanner API returns a JSON response with live prices and bookable flights:
{
"content": {
"results": {
"itineraries": [
{
"price": {"amount": "250.00", "currency": "USD"},
"legIds": ["leg-1"],
"agentIds": ["agent-1"]
}
],
"legs": [
{
"id": "leg-1",
"departure": "2023-12-01T08:00:00",
"arrival": "2023-12-01T11:00:00",
"carrierIds": [1050]
}
],
"carriers": [
{"id": 1050, "name": "Delta Airlines"}
]
}
}
}
Developers can integrate such a request into a travel application to show users real-time flight prices and details.
Documenting APIs
Well-crafted API documentation is a critical piece of infrastructure that can make or break the success of both development teams and products. Whether the API is public, private, or partner, a lack of clear documentation leaves developers guessing about the API's purpose, usage, and constraints.
Many APIs lack sufficient documentation because they utilize traditional documentation tools and practices–i.e., they rely on developers to manually write documentation and keep it in sync with code changes. This approach is time-consuming and often leads to inconsistencies between documentation and the current state of the API.
In response to these issues, modern tools like Multiplayer offer features like System Auto-Documentation to automatically discover and document your API’s architecture. Instead of manually creating diagrams or checking for drift, teams can enable Auto-Documentation to have their system reverse-engineered and documented in real time. As the system evolves, the documentation is updated automatically.

Multiplayer’s System Dashboard
Multiplayer integrates with OpenTelemetry to collect distributed trace data from your application. Once your system is configured to export OpenTelemetry data to Multiplayer, System Auto-Documentation identifies components, APIs, dependencies, platforms, and environments within your software system. This information is then presented in the System Dashboard to provide a real-time visualization of your system's architecture.
Tools for teams working on distributed systems
Learn moreThe three dominant API paradigms
Now that we have explored the three categories of APIs and how to document them, let’s take a look at how APIs can be implemented. There are three dominant API design and implementation paradigms: gRPC, GraphQL, and REST. Each paradigm caters to different needs, balancing trade-offs between performance, flexibility, and ease of use.
The table below summarizes how these paradigms compare across key features, from communication protocols to real-world applications. In the sections that follow, we explore each paradigm in greater detail.
Feature/Aspect | gRPC | GraphQL | REST |
---|---|---|---|
Data Format | Protocol Buffers (binary) | JSON | JSON, XML, etc. |
Performance | High (binary, multiplexed streams) | Moderate (depends on query complexity) | Moderate (over-fetching can occur) |
Flexibility | Low (strict contract) | High (client-defined queries) | Low (fixed endpoints) |
Use Case | Microservices, real-time systems | APIs requiring flexible queries | Simple CRUD operations |
Ease of Use | Moderate (requires learning Protobuf) | Moderate (learning GraphQL syntax) | Easy (familiar HTTP methods) |
Example | Discord (real-time communication) | TMDb API (flexible movie data queries) | Shopify (product management) |
gRPC APIs
gRPC employs protocol buffers (Protobuf) for structured data serialization, enabling efficient, high-performance communication across distributed systems. Its use of HTTP/2 as the underlying transport protocol facilitates multiplexed streams, header compression, and bidirectional communication, reducing latency and resource overhead.
syntax = "proto3";
package chat;
service ChatService {
// Bi-directional streaming for real-time messaging
rpc MessageExchange (stream ChatRequest) returns (stream ChatResponse);
}
message ChatRequest {
string username = 1;
string content = 2;
}
message ChatResponse {
string sender = 1;
string message = 2;
int64 timestamp = 3;
}
Example gRPC protocol buffer schema definition
Companies like Discord have adopted gRPC, illustrating its scalability in real-time environments. Features like bidirectional streaming RPC (MessageExchange) allow simultaneous message transmission and acknowledgment over a single TCP connection. By enforcing strict service contracts through Protobuf schemas, gRPC guarantees type-safe, cross-language interoperability.
GraphQL APIs
GraphQL employs a declarative data-fetching model, allowing clients to specify exact response structures and avoid fetching unneeded data. The Movie Database (TMDb) API demonstrates this capability by allowing clients to fetch nested relational data (e.g., a film’s cast and crew) in a single request. The query below demonstrates field-level specificity, reducing network payloads compared to traditional REST endpoints.
query {
movie(id: 123) {
title
rating
cast {
name
}
}
}
Specifically, this request retrieves only title, rating, and cast data for the specified movie resource. It highlights a key advantage of GraphQL: it allows the client to specify exactly what data it needs, reducing over-fetching or under-fetching of data.
REST APIs
REST follows stateless, resource-centric design principles, utilizing standardized HTTP methods (GET, POST, PUT, DELETE) to perform CRUD operations. In addition, REST APIs often support advanced querying capabilities, such as fetching paginated collections to retrieve large sets of data in manageable chunks, filtering and sorting data using query parameters, and specifying API version numbers.
For example, the request below fetches products from the 2023-10 version of Shopify’s REST API:
GET /admin/api/2023-10/products.json
And this request allows an API consumer to update a product’s details in Shopify:
PUT /admin/api/2023-10/products/123.json
{
"product": {
"title": "Updated Product Name"
}
}
Choosing between GraphQL, REST, and gRPC depends on many factors, such as your application’s data complexity, performance requirements, and communication between client and server. The following section explores common use cases for each API paradigm in different contexts.
Five real-world API use cases
Now that we have introduced common API types and paradigms, let’s examine how each might be used in practice. In this section, we explore a sample e-commerce platform that utilizes private APIs, partner APIs, social media integrations, AI-powered APIs, and audience-focused APIs to deliver uninterrupted and interactive shopping experiences for users.

Example Platform Notebook for a product service API.
Record session replays that include everything from frontend screens to deep platform traces, metrics, and logs
Start For Free1. Private APIs: Fetching product data
E-commerce platforms commonly use private APIs to fetch product data dynamically and display it to users on the front-end application.
GraphQL use case (frontend app to product service)
In our example, the front-end application communicates with the Product Service via a GraphQL API to fetch product details like name, description, price, and availability. In this context, GraphQL provides a flexible way for the front end to request exactly the data it needs from the product service:
query GetProduct($id: ID!) {
product(id: $id) {
name
price
description
inStock
}
}
Fetching only the relevant data (name, price, description, and whether the item is in stock) reduces overfetching and allows for more efficient data transfer between the frontend and backend.
gRPC use case (product service to review service)
For internal communication between microservices, gRPC can be used for its high performance and type safety. Here’s an example of how the Product Service might fetch reviews from the Review Service using gRPC.
// review.proto
service ReviewService {
rpc GetProductReviews (ProductReviewRequest) returns (ProductReviewResponse) {}
}
message ProductReviewRequest {
string product_id = 1;
}
message ProductReviewResponse {
repeated Review reviews = 1;
}
message Review {
string id = 1;
string content = 2;
int32 rating = 3;
}
In review.proto, the gRPC review service is defined. It has a method called GetProductReviews, which takes a ProductReviewRequest message as input and returns a ProductReviewResponse message. This method is intended to retrieve reviews for a specific product.
In the product service, the client makes a gRPC call to the ReviewService to get the reviews for a specific product:
# In Product Service
import grpc
from review_pb2 import ProductReviewRequest
from review_pb2_grpc import ReviewServiceStub
channel = grpc.insecure_channel('review-service:50051')
stub = ReviewServiceStub(channel)
request = ProductReviewRequest(product_id='123')
response = stub.GetProductReviews(request)
for review in response.reviews:
print(f"Review {review.id}: {review.content} - Rating: {review.rating}")
The communication between the client and the service is done using Protocol Buffers for efficient data serialization. This pattern is common in microservices architectures where performance is a priority.
2. Partner APIs: Streamlining payments
Partner APIs enable seamless integration with third-party services, such as payment gateways, to enhance functionality. For example, when it comes to processing payments, integrating with a service like Stripe via REST APIs is common practice.
Here's a simplified example of how the payment service might handle a charge
curl https://api.stripe.com/v1/payment_intents \
-u "sk_test_tR3PYbcVNZZ796tH88S4VQ2u:" \
-d amount=1100 \
-d currency=usd
This request creates and confirms a payment intent with Stripe. Once the API call is made, Stripe handles the core functionality of payment processing.
3. Social media APIs: Collecting user feedback
Social media APIs allow e-commerce platforms to tap into user-generated content and feedback from platforms like Instagram or Facebook.
In our example, the Review Service might use social media APIs to collect user feedback about products. For example, if a user posts about a certain product on Facebook, the Review Service can fetch this data by making the following request:
curl -X GET "https://graph.facebook.com/v17.0/me/feed?fields=id,message,created_time,story&access_token=YOUR_ACCESS_TOKEN"
This feedback is then analyzed to understand user sentiment and improve product offerings.
4. AI APIs: Analyzing sentiment
AI APIs, for example, ChatGPT API, can process and interpret large volumes of unstructured data, including user reviews, social media comments, or customer support transcripts.
Our Review Service could also send user feedback (collected via Social Media APIs) to the ChatGPT API for sentiment analysis:
curl -X POST "https://api.openai.com/v1/chat/completions" -H "Content-Type: application/json" -H "Authorization: Bearer YOUR_OPENAI_API_KEY" -d '{
"model": "gpt-4",
"messages": [
{
"role": "system",
"content": "You are a sentiment analysis tool. Analyze the sentiment of the following user feedbacks and return the results in JSON format."
},
{
"role": "user",
"content": "1. I love this product! It works perfectly.
2. The product is okay, but it could be better.
3. I am very disappointed with this product."
}
],
"max_tokens": 1000
}'
The AI model determines whether the feedback is positive or negative, helping the platform identify areas for improvement or highlighting popular products.
5. Audience APIs: Personalizing marketing campaigns
Audience APIs like the Facebook Audience API enable e-commerce platforms to create targeted marketing campaigns based on user behavior and preferences.
In our example, the Audience Service might track user behavior (e.g., browsing history, purchase history, feedback sentiment) and segment users into categories like "Frequent Buyers" or "Cart Abandoners."
Using the Facebook Audience API, the Audience Service uploads these segments as Custom Audiences or Lookalike Audiences to Facebook. This allows the platform to run personalized ad campaigns, such as retargeting users who abandoned their carts or promoting new products to loyal customers.
Application architecture diagram

Interaction between each service in an e-commerce platform using different APIs.
The above service flow diagram demonstrates the comprehensive API ecosystem of our e-commerce platform, showcasing how different types of APIs work together to create a seamless shopping experience.
The frontend application communicates with the product service using GraphQL for efficient data fetching, while internal services communicate via high-performance gRPC. The payment service integrates with Stripe through REST APIs for secure transactions. The platform leverages social media APIs to gather user feedback, which is then processed by ChatGPT's API for sentiment analysis.
Finally, the audience service helps create targeted marketing campaigns by integrating with external platforms. This architecture demonstrates how various API types, private, partner, social media, AI, and audience, can be orchestrated to create a robust e-commerce system.
The importance of standardized API design
Standardized API design refers to adopting uniform patterns, conventions, and structures to ensure consistency, reliability, and scalability when building APIs. In this section, we explore four critical considerations for designing effective APIs.
Versioning your APIs
Versioning allows APIs to evolve without breaking compatibility with existing clients. A common approach in REST APIs is to embed the version in the URL path.
Example (v1):
GET /v1/product/info
Response: { "product_category": "Cosmetics" }
Example (v2):
GET /v2/product/info
Response: {
"product_category": {
"category_1": "Cosmetics", "subcategory": "Face care"
}
}
The key difference between the two APIs is that v1 (version 1) returns a basic string, while v2 nests details in an object.
Tired of manually updating your system docs, APIs, and diagrams?
Learn How to AutomateClients consuming v2 of API can also show subcategories of the product. Having v2 of API also ensures that clients consuming older versions don't break and also provides the service to deprecate the API in the future when there is no longer traffic to the v1 API.
Similarly, for gRPC, the proto would look as follows:
// v1
package product.v1;
message ProductInfo { string product_category = 1; }
// v2
package product.v2;
message ProductInfo {
message Category {
string primary = 1;
string subcategory = 2;
}
Category product_category = 1;
}
Rate limiting
Any adverse traffic change can break APIs. Therefore, it is essential that rate limiting or tokens are implemented. If APIs are paid partner APIs, it is helpful for the clients to track the number of API calls left. Here is an example of Deepseek API of how they respond with remaining tokens and tokens used
curl "https://api.deepinfra.com/v1/openai/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DEEPINFRA_TOKEN" \
-d '{
"model": "deepseek-ai/DeepSeek-V3",
"messages": [
{
"role": "user",
"content": "Hello!"
}
]
}'
{
"id": "chatcmpl-guMTxWgpFf",
"object": "chat.completion",
"created": 1694623155,
"model": "deepseek-ai/DeepSeek-V3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": " Hi there! It's great to meet you. Is there anything I can assist you with, or would you like to have a conversation?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 15,
"completion_tokens": 16,
"total_tokens": 31,
"estimated_cost": 0.0000268
}
}
Another way to communicate API limits is to include them in response headers. GitHub does this well by documenting their rate limits and adding headers to every response, showing remaining requests and reset times, helping developers manage usage effectively.
$ curl -I https://api.github.com/users/octocat
HTTP/2 200
Date: Tue, 21 Jan 2025 15:23:14 GMT
x-ratelimit-limit: 55
x-ratelimit-remaining: 45
x-ratelimit-used: 3
x-ratelimit-reset: 137210873
This helps clients handle their rate limit programmatically and manage their API usage more effectively. In addition, it protects the API provider from overuse and abuse.
Pagination
Pagination is required when working with large datasets. When an API endpoint returns a large amount of data, pagination will help optimize performance by dividing the data into small, manageable pages.
There are a few common approaches to pagination for efficient data retrieval.
Cursor-based (for dynamic datasets)
This approach uses a token (e.g., timestamp, encoded ID) to mark the dataset’s position, ensuring stable results even if data changes. This approach is ideal for dynamic feeds.
GET /products?cursor=abc123&limit=20
Response:
{
"data": [...],
"next_cursor": "def456"
}
Page-based
This approach splits data into numbered pages, often with a limit of items per page. It is simple but less reliable for real-time data due to shifting offsets.
GET /products?page=2&size=20
Response:
{
"data": [...],
"next_page": 3,
"total_pages": 50
}
Validation for security and performance
Validating the limit or size parameter in pagination improves both security and performance. Without proper validation, a malicious user could exploit these parameters to request excessively large datasets (e.g., limit=200000), leading to server overload and degraded performance.
To prevent this, a maximum allowed limit, such as 100 items per page, should be enforced. Any request exceeding this threshold or containing invalid values must be rejected with an appropriate error response. If the parameter is omitted or improperly set, the system should default to a predefined limit.
Below is an example of an oversized request:
GET /products?cursor=abc123&limit=200000
When proper validation is in place, the server will respond with an appropriate error response:
{
"error": "Invalid parameter",
"message": "The 'limit' parameter cannot exceed 100."
}
Enforcing such policies safeguards the server against denial of service (DoS) attacks and the adverse effects of legitimate requests for large datasets, such as high CPU and memory usage, database locking, slow response times, and overall system instability.
Building API integrations
As shown throughout this article, designing APIs for use in a complex, distributed system is an arduous task that requires technical expertise and close collaboration between engineering teams, business executives, and other stakeholders. It involves a number of design decisions, such as:
- Weighing tradeoffs between different API paradigms
- Creating clear and consistent interfaces
- Establishing API boundaries to minimize coupling between services
- Collaborating on system architecture decisions
For current and future team members to gain a full picture of an API and its evolution, it is important to document both the outcome of the decisions above and the reasoning behind why they were made. In addition, as the API evolves over time and new API calls are written, tested, and debugged, API documentation must keep pace with these changes to stay relevant and usable.
While many teams make a concerted effort to maintain up-to-date documentation, they often fall short due to a number of challenges. Information often gets scattered across different platforms, and while traditional API clients can be useful for individual developer use, they lack features to allow engineers, QA, and stakeholders to collaborate on API interactions together.
Tools like Multiplayer’s Platform Notebooks alleviate these pain points by providing a centralized source of API information alongside other system data, such as architecture diagrams, code repositories, decision records, and other relevant pieces of documentation. In addition, Platform Notebooks provides executable API blocks that allow developers to create API requests, sequence calls, and validate responses within the documentation itself.

Multiplayer’s Platform Notebooks
Finally, the Platform Notebooks feature integrates with Multiplayer’s Platform Debugger so that teams can see backend traces, logs, and metrics for each API execution and debug API failures without manually hunting through logs.
Last thoughts
APIs serve as the foundation of today’s digital ecosystems. From third-party APIs like OpenWeather to private APIs for internal communication, they support diverse use cases across industries such as social media, e-commerce, and marketing. By leveraging tools like GraphQL, REST, and gRPC, developers can tailor API design to specific needs and create scalable, performant, and intuitive APIs.