Skip to main content

Callbacks

Official Documentation

Swagger Documentation

A callback is like leaving your phone number at the restaurant so they call you when the food is ready. In the API world, it works like this:

  1. You (client) want to place an order but don't want to wait. You give the restaurant (server) your phone number (a "callback address") when placing the order.
  2. The restaurant starts preparing the food. This can take some time. The restaurant won't make you wait there standing.
  3. The restaurant calls you when the food is ready. This call is the callback.

How Does This Work in the API?

You make a request to the server asking for something, like "notify me when my order is ready". You also inform where the server should notify you (like a URL, which would be equivalent to your phone number in the previous example). The server sends a message to that URL in the future, when the task is completed.

This functionality (introduced in OpenAPI 3.0) is an important evolution for modern APIs that require bidirectional or event-driven communication.

Callback Benefits​

  • Model asynchronous notifications: Useful for APIs that follow Webhook-based patterns.
  • Complete documentation: Allows describing the entire lifecycle of interaction between client and server.
  • Flexibility: The callback path can be dynamic, adapted to the client's request.
  • Performance: Decreases unnecessary traffic and processing.

These scenarios are common in APIs that implement asynchronous notifications or Webhook-based events.

When to Use?​

  • Webhooks: Notifications for specific events, such as status updates, alerts or messages.
  • Asynchronous processes: When the client needs to be notified after a long-running task is completed.
  • Real-time integrations: Like payment systems, delivery notifications or status updates.

It is not used that much, but it is good to know how it works.


Let's imagine that when we receive a request in an api we need to send to another system (which has another api) that will notify the user. Of course we need to know the other api too.

openapi: 3.0.2
info:
# ...
paths:
# ...
/v1/customers/{customerId}/orders: # Note that the path has a necessary parameter
post:
tags:
- Order Service
description: Place Order
parameters:
- name: customerId # We didn't use the previous id because we changed the definition here.
in: path
description: Customer Id
required: true
style: simple # This is the default
explode: false # This is the default
schema:
type: string
format: uuid
requestBody: # In the body we expect the order with the BeerOrder object
content:
application/json:
schema:
$ref: '#/components/schemas/BeerOrder'
required: false # The object is not mandatory to be passed.
responses:
201:
description: Order Created
headers:
Location:
description: Reference to created Order
style: simple # This is the default
explode: false # This is the default
schema:
type: string
format: uri
400:
description: Bad Request
404:
description: Not Found
409:
description: Conflict
callbacks: # Besides receiving the request we are already preparing another for another system.
orderStatusChange: # Event name
${request.body#/orderStatusCallbackUrl}:
description: Webhook for order status change notifications
post: # If the server is sending data, does it make sense to be something else?
# It is possible that it is, but these are very rare situations.
requestBody: # It is necessary to know the structure that the url above will create.
content:
application/json:
schema:
type: object
properties:
orderId:
type: string
format: uuid
orderStatus:
type: string
responses:
200:
description: Okay
# ...
components:
schemas:
# ...
BeerList:
type: array
items:
$ref: '#/components/schemas/Beer'
BeerOrder:
required:
- customerId
type: object
properties:
id:
type: string
format: uuid
nullable: true # ???
readOnly: true # Will only appear in response, not in request
customerId:
type: string
format: uuid
customerRef:
type: string
nullable: true
beerOrderLines:
type: array
items:
$ref: '#/components/schemas/BeerOrderLine'
orderStatusCallbackUrl: # Will be used in callback
type: string
format: uri
BeerOrderLine:
required:
- orderQuantity
- upc
type: object
properties:
id:
type: string
format: uuid
nullable: true
readOnly: true
beerId:
type: string
format: uuid
readOnly: true
upc:
type: string
orderQuantity:
maximum: 999
minimum: 1
type: integer
quantityAllocated:
type: integer
nullable: true
readOnly: true
parameters:
# ...