OpenAPI for business services describes in machine-readable terms which services your company offers digitally, what data is required, and what responses a calling system can expect. An OpenAPI specification translates an informal process into a verifiable API contract. However, it does not yet allow an AI agent to independently book appointments, confirm prices, or send offers.
In many South Tyrolean SMEs, an inquiry arrives via email, availability is clarified by phone, contact details are transferred to administrative software, and the offer is created in a separate template. These breaks in the process lead to waiting times, follow-up questions, and transmission errors.
From my consulting experience, I know the real bottleneck: The technical endpoint is usually not the issue. Rather, it's unclear which system is binding, who is responsible for data quality, what exceptions apply, and when an action becomes legally or economically binding. You need to clarify these questions before a process becomes a controllable service interface.
OpenAPI for enterprise services: from process to API contract
An API-first planned solution does not begin with a list of technical features. The starting point is a business task that can be clearly described for both people and systems.
A small service company with the following process serves as a consistent example:
- A prospective customer requests a service for a preferred date.
- An employee checks the availability in the deployment plan.
- An appointment will be reserved after a follow-up inquiry.
- Based on the request, the company prepares a draft offer.
- A responsible person checks the price, scope, and conditions.
- A binding offer will only be sent after approval.
Four clearly defined endpoints are defined for this process:
- GET /availability This indicates non-binding availability.
- POST /inquiries Creates a structured query.
- POST /appointments submits a request for an appointment to be reviewed.
- POST /quote-drafts Prepares a draft offer, but not yet a binding offer.
A documented interface describes capabilities. Controlled agent access additionally requires identities, permissions, policies, logging, access limits, and a reliable revocation mechanism.
Step 1: Define the professional boundaries of the company service
A business service is a clearly defined business capability. "Manage appointments" is too broad. "Check available time slots for a service and a day" or "submit a reservation for review" is specific enough.
For each company service, you should answer six questions in writing:
- Purpose: What business result does the service generate?
- Trigger: Who or which system is authorized to initiate the process?
- Inputs: What information is really required?
- Exams: What professional and technical rules apply?
- Status: What states is the process allowed to go through?
- Responsibility: Which source system and which role are legally responsible?
Existing management software doesn't automatically become a clean data model just because it can export data. First, your business needs binding business rules. Only then can the technology implement those rules.
Step 2: Define data model, SSOT and responsibilities
A Single Source of Truth (SSOT ) defines which system is the authoritative source of information and where it can be modified. For example, the calendar can be the source for availability, the CRM for contact details, and the order management system for quote numbers. Our 30-day starter plan for a Single Source of Truth shows you how to establish this system.
For this example, a few defined fields are sufficient to start with:
- service_id: Stable identification of the desired performance.
- preferred_date: preferred date in a specified format.
- contact: the contact option necessary for the process.
- language: desired language, such as German, Italian or English.
- consent: documented consent, if the specific process requires consent.
- idempotency_key: Unique key against unintentional duplicate processing.
- correlation_id: Technical reference for tracking across multiple systems.
Not every field needs to be mandatory at every endpoint. An availability check typically doesn't require any contact. A reservation request, however, does require a way to follow up.
Mandatory fields containing personal data should be limited to the necessary minimum. This complies with the principle of data minimization from Article 5(1)(c) of the General Data Protection Regulation (GDPR ). A technical consent field does not replace either the verification of the legal basis or the provision of clear and understandable data protection information.
Step 3: Describe the endpoints in a technical context
GET /availability: Check availability
This endpoint answers a limited question: Are there any free time slots for a specific service on a specific date? The answer does not yet constitute a binding reservation.
- Role: Website, internal system, or agent with read permission.
- Required fields: service_id and preferred_date.
- Optional information: language for localized instructions.
- Validation: Known service, valid date and allowed query period.
- Source system: Deployment planning or calendar.
- Result: Non-binding time slots.
POST /inquiries: Create inquiry
The endpoint creates a structured process with the status " received" . Successful acceptance only confirms that the system has saved the request.
- Role: Website, employee, or authorized agent.
- Required fields: service_id, contact and language; consent only if required for the process.
- Technical inspection: idempotency_key and correlation_id.
- Source system: CRM or process management.
- Status change: received, needs_review, qualified or rejected.
POST /appointments: Request a reservation
This endpoint is more sensitive from a business perspective because a reservation can influence other interested parties. Depending on the operating model, the result should initially be "pending_approval" rather than automatically " confirmed".
- Role: Employee or system with explicit booking authorization.
- Required fields: service_id, preferred_date, contact, language and idempotency_key.
- Validation: Free appointment, available service and no existing reservation with the same key.
- Source system: binding scheduling or deployment planning.
- Status change: pending_approval, confirmed, rejected, canceled or expired.
POST /quote-drafts: Create a draft offer
A draft proposal is not yet a binding offer. The endpoint may compile existing data and create a working basis. Price, scope of services, taxes, terms and conditions, and validity will subsequently be reviewed by a responsible person.
- Role: Sales representative or system with authorization for drafts.
- Required fields: inquiry_id, language and idempotency_key.
- Validation: Existing inquiry, sufficient master data and valid price basis.
- Source system: Offer or order management.
- Status change: draft, needs_review, approved, rejected or superseded.
Minimal OpenAPI specification for enterprise services
The following YAML draft is based on OpenAPI 3.1.2 and shows the core of the example. The binding reference is the OpenAPI Specification 3.1.2 . For production use, you must adapt server addresses, OAuth endpoints, schemas, response content, and security rules to your specific operation.
The design uses features of OpenAPI 3.1, such as const and a type array. In an OpenAPI 3.0 file, corresponding schema definitions must be formulated differently; therefore, you should not mix examples from both versions without checking them.
openapi: 3.1.2
info:
title: KMU Service API
version: 1.0.0
description: Kontrollierte Service-Schnittstelle für Anfragen, Termine und Angebotsentwürfe
servers:
- url: https://api.example.com/v1
security:
- oauth2: [services.read]
paths:
/availability:
get:
operationId: getAvailability
summary: Unverbindliche Verfügbarkeit lesen
parameters:
- $ref: '#/components/parameters/ServiceId'
- $ref: '#/components/parameters/PreferredDate'
- $ref: '#/components/parameters/CorrelationId'
responses:
'200':
description: Verfügbarkeit erfolgreich gelesen
'400':
$ref: '#/components/responses/ErrorResponse'
'401':
$ref: '#/components/responses/ErrorResponse'
'403':
$ref: '#/components/responses/ErrorResponse'
'429':
$ref: '#/components/responses/ErrorResponse'
'500':
$ref: '#/components/responses/ErrorResponse'
/inquiries:
post:
operationId: createInquiry
summary: Strukturierte Anfrage anlegen
security:
- oauth2: [inquiries.write]
parameters:
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/CorrelationId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/InquiryInput'
responses:
'201':
description: Anfrage angelegt
'400':
$ref: '#/components/responses/ErrorResponse'
'401':
$ref: '#/components/responses/ErrorResponse'
'403':
$ref: '#/components/responses/ErrorResponse'
'409':
$ref: '#/components/responses/ErrorResponse'
'422':
$ref: '#/components/responses/ErrorResponse'
'429':
$ref: '#/components/responses/ErrorResponse'
'500':
$ref: '#/components/responses/ErrorResponse'
/appointments:
post:
operationId: requestAppointment
summary: Terminreservierung zur Freigabe einreichen
security:
- oauth2: [appointments.write]
parameters:
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/CorrelationId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AppointmentInput'
responses:
'201':
description: Reservierungsanfrage angelegt
'409':
$ref: '#/components/responses/ErrorResponse'
'422':
$ref: '#/components/responses/ErrorResponse'
/quote-drafts:
post:
operationId: createQuoteDraft
summary: Unverbindlichen Angebotsentwurf erstellen
security:
- oauth2: [quotes.draft]
parameters:
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/CorrelationId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/QuoteDraftInput'
responses:
'201':
description: Angebotsentwurf angelegt
'422':
$ref: '#/components/responses/ErrorResponse'
components:
securitySchemes:
oauth2:
type: oauth2
flows:
clientCredentials:
tokenUrl: https://auth.example.com/oauth/token
scopes:
services.read: Verfügbarkeiten lesen
inquiries.write: Anfragen anlegen
appointments.write: Reservierungen anfordern
quotes.draft: Angebotsentwürfe erstellen
parameters:
ServiceId:
name: service_id
in: query
required: true
schema:
type: string
PreferredDate:
name: preferred_date
in: query
required: true
schema:
type: string
format: date
IdempotencyKey:
name: Idempotency-Key
in: header
required: true
schema:
type: string
minLength: 16
maxLength: 128
CorrelationId:
name: X-Correlation-ID
in: header
required: true
schema:
type: string
schemas:
Contact:
type: object
properties:
name:
type: string
minLength: 2
email:
type: string
format: email
phone:
type: string
anyOf:
- required: [email]
- required: [phone]
InquiryInput:
type: object
required: [service_id, contact, language]
properties:
service_id:
type: string
contact:
$ref: '#/components/schemas/Contact'
language:
type: string
enum: [de, it, en]
consent:
type: [boolean, 'null']
const: true
AppointmentInput:
type: object
required: [service_id, preferred_date, contact, language]
properties:
service_id:
type: string
preferred_date:
type: string
format: date
contact:
$ref: '#/components/schemas/Contact'
language:
type: string
enum: [de, it, en]
consent:
type: [boolean, 'null']
const: true
QuoteDraftInput:
type: object
required: [inquiry_id, language]
properties:
inquiry_id:
type: string
language:
type: string
enum: [de, it, en]
Error:
type: object
required: [code, message, trace_id]
properties:
code:
type: string
message:
type: string
field:
type: [string, 'null']
trace_id:
type: string
responses:
ErrorResponse:
description: Einheitliche Fehlerantwort
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
The design is intentionally small. A productive service interface additionally requires complete response schemas, timestamps, state models, limits, data protection checks, and automated tests. Each endpoint must clearly define its purpose, inputs, permissions, and expected response.
Clearly define success and failure responses.
An API is only as reliable as its error responses. "Something went wrong" is of no help to either an employee or an external system. A standardized error object should contain at least `code` , `message` , `field` , and `trace_id`.
The following HTTP status codes are used in this example. Their semantics are defined in RFC 9110: HTTP Semantics :
- 200 OK: A read request has been successfully answered.
- 201 Created: A new request, reservation request, or draft has been created.
- 400 Bad Requests: The request is syntactically incorrect or cannot be processed.
- 401 Unauthorized: Valid login details are missing.
- 403 Forbidden: The identity is known, but the person lacks the necessary authorization.
- 409 Conflict: The action conflicts with the current situation, for example in the case of a double reservation.
- 422 Unprocessable Content: The content is syntactically correct, but cannot be processed due to technical rules.
- 429 Too Many Requests: The set rate limit has been exceeded.
- 500 Internal Server Error: An unexpected error occurred in the relevant system.
An error response must not reveal unnecessary internal details. However, it must be specific enough to allow the calling system to correct the process or hand it over to a human.
Separate authentication and authorization
Authentication answers the question: Which identity is accessing the system? Authorization answers: What is this identity allowed to read or change?
A valid bearer token should not grant blanket permission for all actions. OAuth 2.0 allows for the assignment of separate permissions, known as scopes:
- services.read allows reading availability information.
- inquiries.write allows the creation of requests.
- appointments.write It allows reservation requests, but not automatic confirmation.
- quotes.draft Drafts are allowed, but no approval or delivery.
The current recommendations from RFC 9700: Best Current Practice for OAuth 2.0 Security are relevant for the technical design . These include limited token privileges, secure storage, a defined revocation process, and – depending on the security requirements – sender-bound access tokens.
A static API key is only suitable for an isolated, narrowly defined prototype without sensitive data. For production access, external systems, and agents, you need individual identities, limited permissions, expiration times, and a reliable revocation mechanism.
Idempotence, rate limiting, and audit log
Idempotency protects against duplicate write operations. If a system repeatedly sends the same reservation due to a slow connection, the same idempotency_key must result in the existing reservation being sent instead of creating a second appointment.
Rate limiting restricts access within a defined time period. This protects against both abusive access and faulty integrations with too many requests.
An audit log should document:
- which identity accessed it,
- which endpoint was called
- which action and status change was triggered
- whether a human has checked or approved,
- and with which trace_id the process can be traced.
The audit log should not contain unnecessary copies of sensitive information. In many cases, technical references, status changes, and responsible roles are sufficient, while the business data remains in the relevant source system.
An agent API does not yet grant permission for autonomous action.
An agent-enabled website needs more than just machine-readable content. Once an agent is allowed to trigger actions, its access needs clear boundaries.
For small businesses, a three-stage risk logic is practical:
- Low risk – read on: Services, locations, opening hours and non-binding availability can be provided more easily through automation.
- Medium risk – prepare: Inquiries, summaries and draft proposals can be generated automatically, but they require review.
- High risk – take decisive action: Bookings, price commitments, cancellations, payments and sent offers require defined approvals.
A human-in-the-loop is a deliberate control instance. Human approval is appropriate where experience, goodwill, liability, or economic considerations come into play. Our article on controlled bookings by AI agents delves deeper into the transition from information to transaction.
Versioning and operational handover
A published interface changes how things work. Therefore, versioning , backward compatibility, and deprecation notes should be included in the documentation from the very beginning.
- The API version can be identified in the path or via an agreed mechanism.
- Existing mandatory fields will not be removed or fundamentally changed without a new version.
- New optional fields do not affect existing integrations.
- Outdated endpoints receive a deprecation notice and a shutdown date.
- A change log specifies the change, its impact, the responsible party, and the deadline.
- For critical changes, there is a test environment and a fallback plan.
The handover process also includes a professional release rule. This clarifies who owns the data, who checks the quality, who grants permissions, when a process is escalated, and how access is revoked.
90-day plan for OpenAPI enterprise services
Days 1 to 30: Clarify process and responsibility
- Choose a frequent, clearly defined process.
- Document the actual process and its exceptions.
- Determine the source system for each data field.
- Define roles and mandatory approvals.
- Define a small data model with required mandatory fields.
The result is not yet a finished API, but a professionally agreed service contract.
Days 31 to 60: Reading and testing for error cases
- First, implement a read-only endpoint such as /availability.
- Test for valid, missing, incorrect, and contradictory entries.
- Introduce correlation_id, error object, rate limiting, and logging.
- Check values and information in German, Italian and English.
- Have the technical department and the engineering department accept the same test cases.
Days 61 to 90: Allow limited write access
- Start by creating structured queries.
- Secure write operations with idempotence.
- Assign separate permissions for requests, appointments, and drafts.
- Build in a human-in-the-loop for binding actions.
- Test cancellation, failure, retry, and manual takeover.
- Only then allow selected agents to perform limited actions.
Start with the action that is easiest to undo. Controlled writing only follows once reading, note-taking, and drafting are working reliably.
Checklist for the service interface
- Is every company service clearly and technically described?
- Does each endpoint have a clear purpose and a responsible role?
- Is the binding source system known for each field?
- Are mandatory personal data fields limited to the necessary minimum?
- Are data types, formats, and validation rules documented?
- Are success responses and error responses defined in a machine-readable way?
- Are authentication and authorization implemented separately?
- Does an idempotency_key prevent duplicate write operations?
- Does it have rate limiting, an audit log, correlation_id, and trace_id?
- Are status changes and human release limits unambiguous?
- Do versioning, change logs, and shutdown rules exist?
- Can agent access be restricted or revoked immediately?
- Is there a procedure for failures and manual takeover?
- Was the process tested with realistic exceptional cases?
Where does btlabs Core fit into this structure?
btlabs Core is a technically prepared foundation for a central, multilingual, and machine-readable database. Content can be provided from a common source for the website and other channels. This facilitates future service architecture but does not replace the API contract, permissions, approvals, or process ownership.
Booking agents, live price calculators, appointment displays, shops, and other trading functions are optional upgrades and not standard features. Whether an upgrade is worthwhile depends on the process, the existing systems, the risk, and the expected business benefits.
Frequently asked questions about OpenAPI and service interfaces
How much does an OpenAPI interface cost for an SME?
The effort required depends primarily on data quality, existing software, security requirements, and operational exceptions. An initial consultation clarifies whether process consulting, a prototype, or a full production implementation is the most sensible approach.
Can my existing administrative software still be used?
Often yes, provided the software offers reliable data and suitable interfaces. If an API is lacking, a controlled intermediary layer can be useful; direct access to internal databases must be secured with particular care.
Does OpenAPI automatically make my process GDPR-compliant?
No. OpenAPI documents data and access, but it does not replace legal basis, data protection audits, deletion rules, or required contracts. The specification makes mandatory fields and data flows visible and thus more auditable.
Who is liable if an agent confirms an incorrect appointment?
Liability must be clarified legally and contractually for each specific use. Technically, you should limit binding actions, document approvals, and prevent a draft from becoming a commitment without proper review.
When does a service interface require human approval?
Human approval is particularly useful for price commitments, binding bookings, cancellations, payments, and unusual exceptional cases. The greater the financial, legal, or personal impact, the more clearly the human-in-the-loop process must be defined.
How is multilingualism represented in an agent API?
The desired language is passed as a defined value, for example, de, it, or en. Technical content, error responses, and status labels require a central translation logic to ensure that the same business rules apply in every language.
What happens if the calendar or CRM fails?
The interface must provide a clear error status and must not invent availability or prices. For critical processes, you need a manual fallback procedure, a controlled queue, and traceable subsequent processing.
Is one API key sufficient for agent access?
Not usually for production agent access. Individual identities, limited permissions, expiration times, logging, and reliable revocation offer better control.
Does an OpenAPI specification make my website agent-enabled?
No. OpenAPI describes available capabilities, but it doesn't yet create a secure agent API. A robust solution also requires accessible endpoints, identities, authorization, policies, audit logs, permissions, and secure operation.
Should an SME immediately automate bookings and quotes?
In most cases, no. Start with informational materials, then with structured inquiries, and finally with verifiable drafts. Binding actions only follow once data, responsibilities, and controls are functioning smoothly in daily practice.
Conclusion: Introduce OpenAPI enterprise services in a controlled manner
A good service interface doesn't start with as much technology as possible. It starts with an understandable process, a few reliable data points, and clear responsibilities. The OpenAPI specification makes this order machine-readable and auditable.
Based on over 20 years of experience in digitalization and web development, my clear recommendation is: first clarify the process, then document the interface, and only then implement limited automation. This way, your company reduces transmission errors and response times without relinquishing control over binding decisions.