@lap v0.3
# Machine-readable API spec. Each @endpoint block is one API call.
@api seven
@base https://gateway.seven.io/api
@version 1.0.0
@auth OAuth2
@endpoints 51
@hint download_for_search
@toc analytics(4), balance(1), contacts(5), groups(5), hooks(3), journal(4), lookup(5), numbers(6), pricing(1), rcs(3), sms(2), status(1), subaccounts(5), validate_for_voice(1), voice(2), waba(3)

@group analytics
@endpoint GET /analytics/country
@desc Get Analytics By Country
@optional {end: str # End date of the statistics. Defaults to the current day., label: str # Shows only data of a specific label., start: str # Start date of the statistics in the format YYYY-MM-DD. By default, the date of 30 days ago is set., subaccounts: str # Receive the data only for the main account, all your (sub-)accounts or only for specific subaccounts.}
@returns(200) OK

@endpoint GET /analytics/date
@desc Get Analytics By Date
@optional {end: str # End date of the statistics. Defaults to the current day., label: str # Shows only data of a specific label., start: str # Start date of the statistics in the format YYYY-MM-DD. By default, the date of 30 days ago is set., subaccounts: str # Receive the data only for the main account, all your (sub-)accounts or only for specific subaccounts.}
@returns(200) OK

@endpoint GET /analytics/label
@desc Get Analytics By Label
@optional {end: str # End date of the statistics. Defaults to the current day., label: str # Shows only data of a specific label., start: str # Start date of the statistics in the format YYYY-MM-DD. By default, the date of 30 days ago is set., subaccounts: str # Receive the data only for the main account, all your (sub-)accounts or only for specific subaccounts.}
@returns(200) OK

@endpoint GET /analytics/subaccount
@desc Get Analytics By Label
@optional {end: str # End date of the statistics. Defaults to the current day., label: str # Shows only data of a specific label., start: str # Start date of the statistics in the format YYYY-MM-DD. By default, the date of 30 days ago is set., subaccounts: str # Receive the data only for the main account, all your (sub-)accounts or only for specific subaccounts.}
@returns(200) OK

@endgroup

@group balance
@endpoint GET /balance
@desc Get Balance
@returns(200) {amount: num(float), currency: str} # OK

@endgroup

@group contacts
@endpoint GET /contacts
@desc List Contacts
@returns(200) {data: [map], pagingMetadata: map{offset: int, count: int, total: int, limit: int, has_more: bool}} # OK

@endpoint POST /contacts
@desc Create Contact
@returns(200) {id: int(int32), avatar: str, validation: map{state: str, timestamp: str}, initials: map{initials: str, color: str}, properties: map{firstname: str, lastname: str, mobile_number: int(int64), home_number: str, email: str, address: str, postal_code: str, city: str, birthday: str(date), notes: str}, groups: [int], created: str} # OK

@endpoint DELETE /contacts/{id}
@desc Delete Contact
@required {id: str # The ID of the contact for deletion.}
@returns(200) {error: str, success: bool} # OK

@endpoint GET /contacts/{id}
@desc Get Contact
@required {id: str # The ID of the contact for retrieval.}
@returns(200) {id: int(int32), avatar: str, validation: map{state: str, timestamp: str}, initials: map{initials: str, color: str}, properties: map{firstname: str, lastname: str, mobile_number: int(int64), home_number: str, email: str, address: str, postal_code: str, city: str, birthday: str(date), notes: str}, groups: [int], created: str} # OK

@endpoint PATCH /contacts/{id}
@desc Update Contact
@required {id: str # The ID of the contact for deletion.}
@returns(200) {id: int(int32), avatar: str, validation: map{state: str, timestamp: str}, initials: map{initials: str, color: str}, properties: map{firstname: str, lastname: str, mobile_number: int(int64), home_number: str, email: str, address: str, postal_code: str, city: str, birthday: str(date), notes: str}, groups: [int], created: str} # OK

@endgroup

@group groups
@endpoint GET /groups
@desc List Groups
@returns(200) {data: [map], pagingMetadata: map{offset: int, count: int, total: int, limit: int, has_more: bool}} # OK

@endpoint POST /groups
@desc Create Group
@returns(200) {id: int, name: str, members_count: int, has_more: bool} # OK

@endpoint DELETE /groups/{id}
@desc Delete Group
@required {id: str # The ID of the group for deletion.}
@returns(200) {success: bool} # OK

@endpoint GET /groups/{id}
@desc Get Group
@required {id: int # The ID of the group for retrieval.}
@returns(200) {id: int, name: str, members_count: int, has_more: bool} # OK

@endpoint PATCH /groups/{id}
@desc Update Group
@required {id: int # The ID of the group for updating.}
@returns(200) {id: int, name: str, members_count: int, has_more: bool} # OK

@endgroup

@group hooks
@endpoint DELETE /hooks
@desc Delete Hook
@returns(200) {code: str, error_message: str, id: int, success: bool} # OK

@endpoint GET /hooks
@desc List Hooks
@returns(200) {data: [map]} # OK

@endpoint POST /hooks
@desc Create Hook
@returns(200) {code: str, error_message: str, id: int, success: bool} # OK

@endgroup

@group journal
@endpoint GET /journal/outbound
@desc Get outbound messages
@optional {id: int # The ID of a message, date_from: str # A start date from which the search should start, date_to: str # An end date up to which the search is to be performed, to: str # The receivers phone number in any format., state: str # The status of the message. - could be e.g. completed / failed for Voice or DELIVERED / NOTDELIVERED etc. for SMS, limit: int # Limits the number of entries to be returned., offset: int # Starting point from which entries are to be queried.}
@returns(200) OK

@endpoint GET /journal/inbound
@desc Get inbound messages
@optional {id: int # The ID of a message, date_from: str # A start date from which the search should start, date_to: str # An end date up to which the search is to be performed, to: str # The receivers phone number in any format., state: str # The status of the message. - could be e.g. completed / failed for Voice or DELIVERED / NOTDELIVERED etc. for SMS, limit: int # Limits the number of entries to be returned., offset: int # Starting point from which entries are to be queried.}
@returns(200) OK

@endpoint GET /journal/replies
@desc Get message replies
@optional {id: int # The ID of a message, date_from: str # A start date from which the search should start, date_to: str # An end date up to which the search is to be performed, to: str # The receivers phone number in any format., state: str # The status of the message. - could be e.g. completed / failed for Voice or DELIVERED / NOTDELIVERED etc. for SMS, limit: int # Limits the number of entries to be returned., offset: int # Starting point from which entries are to be queried.}
@returns(200) OK

@endpoint GET /journal/voice
@desc Get voice journal
@optional {id: int # The ID of a message, date_from: str # A start date from which the search should start, date_to: str # An end date up to which the search is to be performed, to: str # The receivers phone number in any format., state: str # The status of the message. - could be e.g. completed / failed for Voice or DELIVERED / NOTDELIVERED etc. for SMS, limit: int # Limits the number of entries to be returned., offset: int # Starting point from which entries are to be queried.}
@returns(200) OK

@endgroup

@group lookup
@endpoint GET /lookup/cnam
@desc Lookup Caller Name
@required {number: str # The phone number to look up}
@returns(200) {code: num, success: str, name: str, number: str} # OK

@endpoint GET /lookup/format
@desc Lookup Format
@required {number: str # The phone number to look up}
@returns(200) {success: bool, international: str, international_formatted: str, national: str, country_iso: str, country_name: str, country_code: str} # OK

@endpoint GET /lookup/hlr
@desc Lookup HLR
@required {number: str # The phone number to look up}
@returns(200) {international_formatted: str, country_name: str, country_code: str, international_format_number: str, national_format_number: str, country_prefix: str, current_carrier: map{network_code: str, name: str, country: str, network_type: str}, original_carrier: map{network_code: str, name: str, country: str, network_type: str}, lookup_outcome: str, lookup_outcome_message: str, valid_number: str, reachable: str, roaming: map{status: str, roaming_country_code: str, roaming_network_code: str, roaming_network_name: str}} # OK

@endpoint GET /lookup/mnp
@desc Lookup MNP
@required {number: str # The phone number to look up}
@returns(200) {code: num, success: bool, price: num(float), mnp: map{country: str, number: str, national_format: str, international_formatted: str, network: str, mccmnc: str, isPorted: bool, network_type: str}} # OK

@endpoint GET /lookup/rcs
@desc Lookup RCS Capabilities
@required {number: str # The phone number to look up}
@returns(200) OK

@endgroup

@group numbers
@endpoint GET /numbers/active
@desc List Active Numbers
@returns(200) {activeNumbers: [map]} # OK

@endpoint DELETE /numbers/active/{number}
@desc Delete Number
@required {number: str # The phone number to delete.}
@returns(200) {success: bool} # OK

@endpoint GET /numbers/active/{number}
@desc Get Number
@required {number: str # The phone number to retrieve.}
@returns(200) {country: str, number: str, friendly_name: str, billing: map{fees: map{setup: num, basic_charge: num, sms_mo: int(int32), voice_mo: int(int32)}, payment_interval: str}, features: map{sms: bool, a2p_sms: bool, voice: bool}, forward_sms_mo: map{sms: map{number: str, enabled: bool}, email: map{address: [str], enabled: bool}, slack: map{uri: str, enabled: bool}}, expires: str, created: str} # OK

@endpoint PATCH /numbers/active/{number}
@desc Update Number
@required {number: str # The phone number to update details for.}
@returns(200) {country: str, number: str, friendly_name: str, billing: map{fees: map{setup: num, basic_charge: num, sms_mo: int(int32), voice_mo: int(int32)}, payment_interval: str}, features: map{sms: bool, a2p_sms: bool, voice: bool}, forward_sms_mo: map{sms: map{number: str, enabled: bool}, email: map{address: [str], enabled: bool}, slack: map{uri: str, enabled: bool}}, expires: str, created: str} # OK

@endpoint GET /numbers/available
@desc Get Available Numbers
@optional {country: str # The ISO 3166-1 alpha-2 country code of the country to search for available numbers in., features_sms: bool # If set to true, only numbers that support SMS will be returned., features_a2p_sms: bool # If set to true, only numbers that support A2P SMS will be returned., features_voice: bool # If set to true, only numbers that support voice will be returned.}
@returns(200) {availableNumbers: [map]} # OK

@endpoint POST /numbers/order
@desc Order Number
@returns(200) {error: str, success: bool} # OK

@endgroup

@group pricing
@endpoint GET /pricing
@desc Get Pricing
@optional {country: str # The countries ISO code to get pricing for. Example values are "de" for Germany or "fr" for France. Omit to show pricing for all channels.}
@returns(200) {countCountries: int, countNetworks: int, countries: [map]} # OK

@endgroup

@group rcs
@endpoint POST /rcs/events
@desc Trigger RCS Event
@returns(200) {success: bool} # OK

@endpoint POST /rcs/messages
@desc Send RCS
@returns(200) {balance: num, debug: str, messages: [map], sms_type: str, success: str, total_price: num} # Success

@endpoint DELETE /rcs/messages/{id}
@desc Delete RCS
@required {id: str # The message ID for deletion}
@returns(200) {success: bool} # OK

@endgroup

@group sms
@endpoint DELETE /sms
@desc Delete Sms
@returns(200) {deleted: [int], success: bool} # Success

@endpoint POST /sms
@desc Send Sms
@returns(200) {balance: num, debug: str, messages: [map], sms_type: str, success: str, total_price: num} # Success

@endgroup

@group status
@endpoint GET /status
@desc Get SMS Status
@required {msg_id: str # A comma separated list of SMS IDs to check}
@returns(200) Success

@endgroup

@group subaccounts
@endpoint GET /subaccounts/list
@desc List Subaccounts
@optional {id: str # The ID of a subaccount. This will give you only the data for a specific subaccount.}
@returns(200) OK

@endpoint POST /subaccounts/create
@desc Create Subaccount
@returns(200) {error: str, subaccount: map{id: str, username: str, company: str, balance: str, total_usage: str, auto_topup: map{amount: str, threshold: str}, contact: map{email: str, name: str}}, success: bool} # OK

@endpoint POST /subaccounts/update
@desc Automatic Balance Transfer
@returns(200) {error: str, success: bool} # OK

@endpoint POST /subaccounts/transfer_credits
@desc Manual Credit Transfer
@returns(200) {error: str, success: bool} # OK

@endpoint POST /subaccounts/delete
@desc Delete Subaccount
@returns(200) {error: str, success: bool} # OK

@endgroup

@group validate_for_voice
@endpoint POST /validate_for_voice
@desc Validate Caller ID for Voice
@returns(200) Success

@endgroup

@group voice
@endpoint POST /voice
@desc Send text-to-speech Voice Call
@returns(200) Success

@endpoint POST /voice/{call_id}/hangup
@desc End Voice Call
@required {call_id: str # The ID of the call to be ended}
@returns(200) {error: str, success: bool} # Success

@endgroup

@group waba
@endpoint POST /waba/messages
@desc Send WhatsApp Message
@required {from: str # The WhatsApp sender number., to: str # The recipient phone number.}
@optional {type: str(template/text/image/video/audio/document/sticker/location/contacts/interactive) # The message type. Required for structured messages. Omit for simple freetext messages using the "text" parameter., template: str # The template name. Required when type is "template"., language: str # The language code for the template (e.g. "de", "en"). Required when type is "template"., text: str # The free text message content. Used for non-template messages within an active conversation., delay: str # Date/Time for delayed dispatch - expects a date time like "2026-02-10 09:00:00" or a Unix timestamp., label: str # A custom label for sorting analytics., foreign_id: str # Identifier to return in callbacks for status reports etc., ttl: int # Time to live in minutes for the message., performance_tracking: bool=false # Enable performance tracking for found URLs., components: map{header: [str], body: [str], buttons: [map]} # Template components for parameter substitution. Values are positional and replace {{1}}, {{2}}, etc. in the template., url: str # Public URL of the media file. Required for image, video, audio, document, and sticker types., caption: str # Caption for the media file. Optional for image, video, and document types., filename: str # Filename for the document. Required when type is "document"., latitude: num(double) # Latitude of the location. Required when type is "location"., longitude: num(double) # Longitude of the location. Required when type is "location"., name: str # Name of the location. Optional when type is "location"., address: str # Address of the location. Optional when type is "location"., contacts: [map{name!: map, phones!: [map]}] # Contact cards to send. Required when type is "contacts"., interactive_type: str(button/list) # Sub-type for interactive messages. Required when type is "interactive"., body: str # Body text for interactive messages., header: str # Header text for interactive messages., footer: str # Footer text for interactive messages., buttons: [map{id!: str, title!: str}] # Buttons for interactive button messages. Max 3 buttons., button_text: str # Button text for interactive list messages., sections: [map{title!: str, rows!: [map]}] # Sections for interactive list messages.}
@returns(200) {success: str, total_price: num, balance: num, debug: str, sms_type: str, messages: [map]} # OK
@errors {400: Bad Request}

@endpoint DELETE /waba/messages/{id}
@desc Delete WhatsApp Message
@required {id: str # The ID of the message to delete.}
@returns(200) {success: bool} # OK
@errors {400: Bad Request, 404: Not Found}

@endpoint POST /waba/events
@desc Trigger WhatsApp Event
@required {event: str(read/is_typing/reaction) # The event type to trigger.}
@optional {from: str # The WhatsApp sender number. Not used for reaction events., to: str # The recipient phone number. Not used for reaction events. At least one of "to" or "msg_id" must be provided., msg_id: str # The ID of the message to which the event refers. At least one of "to" or "msg_id" must be provided., message_id: str # The ID of the message to react to. Required when event is "reaction"., emoji: str # Emoji for the reaction. Required when event is "reaction".}
@returns(200) {success: bool} # OK
@errors {400: Bad Request}

@endgroup

@end
