On this page
TransferGo
Founded in 2012, TransferGo provides international money transfer services with a focus on accessibility, speed, and affordability for migrants. The company operates in over 160 countries and serves millions of customers globally, ensuring fast and reliable cross-border payments.
tl;dr just go and have a look atfull production-used AsyncAPI document
Challenges
In 2021, TransferGo's Backend Guild identified challenges with documenting both REST and asynchronous APIs. Different teams used varying approaches, which created inconsistencies and difficulties in maintaining up-to-date API schemas. As services grew past 50 and more events were introduced, inconsistencies and invalid schemas emerged. Additionally, YAML-based documentation was not user-friendly, making discoverability and adoption harder. With over 300 channels, visibility into published events and ensuring trust across distributed systems became a significant challenge.
Solution
TransferGo adopted the AsyncAPI specification to unify documentation practices and improve developer experience. Instead of an API-first approach, they introduced a code-first documentation model using an internal library. This library leverages Reflection in PHP and .NET to generate AsyncAPI schemas directly from DTOs, reducing duplication and ensuring consistency.
To maintain schema quality, TransferGo integrated AsyncAPI CLI into their pipelines, automating validation and optimization of large schemas. They also contributed to schema scoring capabilities in AsyncAPI CLI, encouraging teams to keep docs clean and consistent.
For accessibility, TransferGo automated publishing of AsyncAPI definitions using GitHub Actions. Schemas are stored in S3 and surfaced through Port.io Developer Portal, providing a single interface for developers to browse, search, and visualize service contracts.
At scale, TransferGo introduced Event Catalog to map their 300+ channels and highlight integration gaps. For testing, they adopted contract testing with Microcks and LocalStack, integrated into Jenkins CI, enabling validation of service interactions against AsyncAPI definitions. Finally, their internal CLI tool, API Guardian, helps ensure schema coverage by comparing AsyncAPI definitions with deployed infrastructure.
Use Case
TransferGo uses AsyncAPI to unify async API documentation across services, generate schemas from code via internal libraries, validate and optimize schemas in CI pipelines, publish schemas to Port.io Developer Portal for centralized access, build an Event Catalog for visibility into 300+ channels, and support contract testing with Microcks.
More Details
Testing strategy
Contract testing with Microcks and LocalStack integrated into Jenkins CI, validating message-driven services without requiring cloud infrastructure.
Approach to code generation
Code-first generation of AsyncAPI schemas is achieved via internal libraries in PHP and .NET. These libraries automatically reflect DTOs into message payload definitions, ensuring up-to-date and consistent documentation across services.
Architecture
TransferGo relies heavily on an Event Driven Architecture, ensuring instant money transfers and reliable asynchronous communication. Services publish and consume events primarily through AWS Simple Notification Service (SNS) and Simple Queue Service (SQS), with Kafka used where applicable. Symfony-based workers handle incoming messages, while validation and coverage tools ensure contracts remain trustworthy.
More Details about AsyncAPI
How AsyncAPI documents are stored
Schemas are stored in GitHub repositories and automatically published to an S3 bucket. Port.io Developer Portal ingests these schemas to make them accessible to developers.
Where maintainers edit AsyncAPI documents
Documentation is maintained via code-first libraries. GitHub Actions pipelines validate and publish updates automatically. AsyncAPI CLI is used for validation, optimization, and schema scoring.
What extensions are used
None
How documentation is generated
AsyncAPI React component was initially used for rendering. Today, Port.io Developer Portal serves as the central platform, presenting all AsyncAPI schemas in a unified, visual interface.
What bindings are used
None
What tools are used
TransferGo relies on AsyncAPI CLI, AsyncAPI React, AsyncAPI Modelina, Port.io Developer Portal, Event Catalog, Microcks, LocalStack, and API Guardian (internal CLI).
Schemas
Storage strategy
Schemas are generated from service code and stored in GitHub repositories, with automated publishing to an S3 bucket for central access.
Schema Registry
None, schemas are distributed via S3 and Port.io Developer Portal.
Versioning of schemas
Versioning is handled per repository and service team, aligned with service releases.
Validation of message schemas
AsyncAPI CLI is used to validate schemas for correctness and optimize file sizes. Jenkins CI pipelines enforce schema validation during builds.
Additional Resources
See slides from 2023 that show early days of adoption
Production-use AsyncAPI document
1asyncapi: 3.0.02info:3 title: Remittance Service Event Bus Example4 version: 1.0.05 description: |6 Example AsyncAPI 2.6.0 model for a Remittance Service.7 A user makes a cross-border transaction request.8 Events are published to AWS SNS, which pushes them to an SQS queue.9 Downstream services consume the event from SQS.10servers:11 aws:12 host: '{service}.{region}.amazonaws.com'13 protocol: https14 description: AWS endpoints for SNS and SQS.15 variables:16 service:17 enum:18 - sns19 - sqs20 default: sns21 region:22 default: us-east-123 description: AWS region used for the SNS/SQS resources.24channels:25 remittance-transactions-topic:26 address: sns/remittance-transactions-topic27 messages:28 publishRemittanceTransactionToSNS:29 $ref: '#/components/messages/RemittanceTransactionRequested'30 description: SNS topic for remittance transaction events.31 remittance-transactions-queue:32 address: sqs/remittance-transactions-queue33 messages:34 consumeRemittanceTransactionFromSQS:35 $ref: '#/components/messages/RemittanceTransactionRequested'36 description: SQS queue that receives messages forwarded from SNS topic via37 subscription.38operations:39 publishRemittanceTransactionToSNS:40 action: receive41 channel:42 $ref: '#/channels/remittance-transactions-topic'43 summary: Publish RemittanceTransactionRequested event to SNS topic44 messages:45 - $ref: '#/channels/remittance-transactions-topic/messages/publishRemittanceTransactionToSNS'46 consumeRemittanceTransactionFromSQS:47 action: send48 channel:49 $ref: '#/channels/remittance-transactions-queue'50 summary: >-51 Consumer service polls SQS to consume RemittanceTransactionRequested52 events.53 messages:54 - $ref: '#/channels/remittance-transactions-queue/messages/consumeRemittanceTransactionFromSQS'55components:56 messages:57 RemittanceTransactionRequested:58 name: RemittanceTransactionRequested59 title: Remittance Transaction Requested60 summary: Event emitted when a user requests to send money cross-border.61 contentType: application/json62 payload:63 type: object64 required:65 - transactionId66 - transactionType67 - createdAt68 - sender69 - receiver70 - amount71 - currency72 - paymentMethod73 properties:74 transactionId:75 type: string76 format: uuid77 description: Unique transaction identifier.78 transactionType:79 type: string80 description: Type of transaction.81 createdAt:82 type: string83 format: date-time84 description: ISO8601 timestamp for when the request was made.85 sender:86 type: object87 required:88 - name89 - email90 - country91 properties:92 name:93 type: string94 email:95 type: string96 format: email97 country:98 type: string99 description: ISO 3166-1 alpha-2 country code100 receiver:101 type: object102 required:103 - name104 - email105 - country106 properties:107 name:108 type: string109 email:110 type: string111 format: email112 country:113 type: string114 description: ISO 3166-1 alpha-2 country code115 amount:116 type: number117 format: double118 description: Amount requested to transfer.119 currency:120 type: string121 description: ISO 4217 currency code.122 paymentMethod:123 type: string124 description: Payment method used to fund the transaction.125 enum:126 - card127 - wire_transfer128 - bank_account129 examples:130 - name: remittance.transaction.requested.example131 summary: Example remittance transaction request132 payload:133 transactionId: 33333333-3333-3333-3333-333333333333134 transactionType: remittance.requested135 createdAt: '2025-09-16T10:15:00Z'136 sender:137 name: Jonas Petrauskas138 email: jonas.petrauskas@example.lt139 country: LT140 receiver:141 name: Olena Shevchenko142 email: olena.shevchenko@example.ua143 country: UA144 amount: 750145 currency: EUR146 paymentMethod: wire_transfer