late-sdk 0.0.726 → 0.0.728
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +19 -0
- data/docs/AttachNumberToSipTrunk200Response.md +22 -0
- data/docs/AttachNumberToSipTrunkRequest.md +18 -0
- data/docs/CreatePostRequest.md +1 -1
- data/docs/CreateSipTrunk201Response.md +34 -0
- data/docs/CreateSipTrunk201ResponseTermination.md +20 -0
- data/docs/CreateSipTrunkRequest.md +24 -0
- data/docs/DetachNumberFromSipTrunk200Response.md +20 -0
- data/docs/GetPhoneNumber200ResponsePhoneNumber.md +3 -1
- data/docs/GetSipTrunk200Response.md +34 -0
- data/docs/GetSipTrunk200ResponseNumbersInner.md +20 -0
- data/docs/LinkedInPlatformData.md +1 -1
- data/docs/ListPhoneNumbers200ResponseNumbersInner.md +2 -0
- data/docs/ListSipTrunks200Response.md +20 -0
- data/docs/ListSipTrunks200ResponseTrunksInner.md +32 -0
- data/docs/ListSipTrunks200ResponseTrunksInnerTermination.md +20 -0
- data/docs/PostsApi.md +1 -1
- data/docs/RotateSipTrunkCredentials200Response.md +20 -0
- data/docs/VoiceApi.md +485 -0
- data/lib/zernio-sdk/api/posts_api.rb +2 -2
- data/lib/zernio-sdk/api/voice_api.rb +447 -0
- data/lib/zernio-sdk/models/attach_number_to_sip_trunk200_response.rb +165 -0
- data/lib/zernio-sdk/models/attach_number_to_sip_trunk_request.rb +165 -0
- data/lib/zernio-sdk/models/create_post_request.rb +1 -1
- data/lib/zernio-sdk/models/create_sip_trunk201_response.rb +255 -0
- data/lib/zernio-sdk/models/create_sip_trunk201_response_termination.rb +158 -0
- data/lib/zernio-sdk/models/create_sip_trunk_request.rb +283 -0
- data/lib/zernio-sdk/models/detach_number_from_sip_trunk200_response.rb +157 -0
- data/lib/zernio-sdk/models/get_phone_number200_response_phone_number.rb +15 -4
- data/lib/zernio-sdk/models/get_sip_trunk200_response.rb +256 -0
- data/lib/zernio-sdk/models/get_sip_trunk200_response_numbers_inner.rb +157 -0
- data/lib/zernio-sdk/models/linked_in_platform_data.rb +1 -1
- data/lib/zernio-sdk/models/list_phone_numbers200_response_numbers_inner.rb +12 -1
- data/lib/zernio-sdk/models/list_sip_trunks200_response.rb +159 -0
- data/lib/zernio-sdk/models/list_sip_trunks200_response_trunks_inner.rb +245 -0
- data/lib/zernio-sdk/models/list_sip_trunks200_response_trunks_inner_termination.rb +156 -0
- data/lib/zernio-sdk/models/rotate_sip_trunk_credentials200_response.rb +156 -0
- data/lib/zernio-sdk/version.rb +1 -1
- data/lib/zernio-sdk.rb +12 -0
- data/openapi.yaml +271 -3
- data/spec/api/posts_api_spec.rb +1 -1
- data/spec/api/voice_api_spec.rb +82 -0
- data/spec/models/attach_number_to_sip_trunk200_response_spec.rb +48 -0
- data/spec/models/attach_number_to_sip_trunk_request_spec.rb +36 -0
- data/spec/models/create_sip_trunk201_response_spec.rb +88 -0
- data/spec/models/create_sip_trunk201_response_termination_spec.rb +42 -0
- data/spec/models/create_sip_trunk_request_spec.rb +58 -0
- data/spec/models/detach_number_from_sip_trunk200_response_spec.rb +42 -0
- data/spec/models/get_phone_number200_response_phone_number_spec.rb +6 -0
- data/spec/models/get_sip_trunk200_response_numbers_inner_spec.rb +42 -0
- data/spec/models/get_sip_trunk200_response_spec.rb +88 -0
- data/spec/models/list_phone_numbers200_response_numbers_inner_spec.rb +6 -0
- data/spec/models/list_sip_trunks200_response_spec.rb +42 -0
- data/spec/models/list_sip_trunks200_response_trunks_inner_spec.rb +82 -0
- data/spec/models/list_sip_trunks200_response_trunks_inner_termination_spec.rb +42 -0
- data/spec/models/rotate_sip_trunk_credentials200_response_spec.rb +42 -0
- data/zernio-sdk-0.0.728.gem +0 -0
- metadata +51 -3
- data/zernio-sdk-0.0.726.gem +0 -0
data/openapi.yaml
CHANGED
|
@@ -5461,7 +5461,7 @@ components:
|
|
|
5461
5461
|
description: Set to true to disable automatic link previews for URLs in the post content (default is false)
|
|
5462
5462
|
reshareUrl:
|
|
5463
5463
|
type: string
|
|
5464
|
-
description: "LinkedIn post link to repost (use the post's \"Copy link to post\" action), or a urn:li:share / urn:li:ugcPost / urn:li:groupPost URN.
|
|
5464
|
+
description: "LinkedIn post link to repost (use the post's \"Copy link to post\" action), or a urn:li:share / urn:li:ugcPost / urn:li:groupPost URN. The published post is always a reshare authored by your account with the original embedded underneath: with content your text is the commentary (LinkedIn's \"repost with your thoughts\"), and with no content it publishes as a text-free reshare. Note that a text-free reshare is NOT LinkedIn's one-click \"Repost\" (the feed treatment where the original author stays the author); LinkedIn's API exposes no way to create that, so the post still appears authored by you with the original embedded. Mutually exclusive with media. Works on personal profiles and organization pages."
|
|
5465
5465
|
geoRestriction:
|
|
5466
5466
|
$ref: '#/components/schemas/GeoRestriction'
|
|
5467
5467
|
poll:
|
|
@@ -14022,7 +14022,7 @@ paths:
|
|
|
14022
14022
|
summary: Create post
|
|
14023
14023
|
description: |
|
|
14024
14024
|
Create and optionally publish a post. Immediate posts (`publishNow: true`) include `platformPostUrl` in the response.
|
|
14025
|
-
Content is optional when media is attached, all platforms have `customContent`, every platform entry is an X Article (`platformSpecificData.article`), or every platform entry is a LinkedIn
|
|
14025
|
+
Content is optional when media is attached, all platforms have `customContent`, every platform entry is an X Article (`platformSpecificData.article`), or every platform entry is a LinkedIn text-free reshare (`platformSpecificData.reshareUrl` with no text). See each platform's schema for media constraints.
|
|
14026
14026
|
|
|
14027
14027
|
## Idempotency
|
|
14028
14028
|
|
|
@@ -14056,7 +14056,7 @@ paths:
|
|
|
14056
14056
|
title: { type: string }
|
|
14057
14057
|
content:
|
|
14058
14058
|
type: string
|
|
14059
|
-
description: 'Post caption/text. Optional when media is attached, all platforms have customContent, every platform entry is an X Article (platformSpecificData.article), or every platform entry is a LinkedIn
|
|
14059
|
+
description: 'Post caption/text. Optional when media is attached, all platforms have customContent, every platform entry is an X Article (platformSpecificData.article), or every platform entry is a LinkedIn text-free reshare (platformSpecificData.reshareUrl with no text). Required for other text-only posts.'
|
|
14060
14060
|
mediaItems:
|
|
14061
14061
|
type: array
|
|
14062
14062
|
items: { $ref: '#/components/schemas/MediaItem' }
|
|
@@ -31938,6 +31938,7 @@ paths:
|
|
|
31938
31938
|
telnyxOrderId: { type: [string, "null"], description: Present once the number order has been placed (i.e. the requirement group was approved). Absent while still in identity review. }
|
|
31939
31939
|
monthlyCents: { type: integer, description: Per-country monthly price in cents ($2..$25). }
|
|
31940
31940
|
hostedByZernio: { type: boolean, description: "False for numbers you brought yourself (connected via Meta embedded signup) — they live on your own carrier, so SMS/Calls can't be enabled on them." }
|
|
31941
|
+
sipTrunkId: { type: [string, "null"], description: 'SIP trunk the number is attached to; null when not trunked. While attached, enabling Calls or WhatsApp calling, requesting WhatsApp verification, and releasing the number all return 409.' }
|
|
31941
31942
|
profileId: { type: object }
|
|
31942
31943
|
provisionedAt: { type: string, format: date-time }
|
|
31943
31944
|
metaPreverifiedId: { type: string }
|
|
@@ -32028,6 +32029,7 @@ paths:
|
|
|
32028
32029
|
endUserLastName: { type: [string, "null"] }
|
|
32029
32030
|
regulatoryDeclineReason: { type: [string, "null"], description: Reviewer rejection reason when status is regulatory_declined. }
|
|
32030
32031
|
provisionedAt: { type: string, format: date-time }
|
|
32032
|
+
sipTrunkId: { type: [string, "null"], description: 'SIP trunk the number is attached to; null when not trunked. While attached, enabling Calls or WhatsApp calling, requesting WhatsApp verification, and releasing the number all return 409.' }
|
|
32031
32033
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
32032
32034
|
'404': { $ref: '#/components/responses/NotFound' }
|
|
32033
32035
|
delete:
|
|
@@ -32069,6 +32071,7 @@ paths:
|
|
|
32069
32071
|
'400': { description: Phone number is already released or being released }
|
|
32070
32072
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
32071
32073
|
'404': { $ref: '#/components/responses/NotFound' }
|
|
32074
|
+
'409': { description: 'The number is attached to a SIP trunk; detach it first (code invalid_resource_state).' }
|
|
32072
32075
|
|
|
32073
32076
|
/v1/phone-numbers/purchase:
|
|
32074
32077
|
post:
|
|
@@ -32479,6 +32482,7 @@ paths:
|
|
|
32479
32482
|
telnyxOrderId: { type: [string, "null"], description: Present once the number order has been placed (i.e. the requirement group was approved). Absent while still in identity review. }
|
|
32480
32483
|
monthlyCents: { type: integer, description: Per-country monthly price in cents ($2..$25). }
|
|
32481
32484
|
hostedByZernio: { type: boolean, description: "False for numbers you brought yourself (connected via Meta embedded signup) — they live on your own carrier, so SMS/Calls can't be enabled on them." }
|
|
32485
|
+
sipTrunkId: { type: [string, "null"], description: 'SIP trunk the number is attached to; null when not trunked. While attached, enabling Calls or WhatsApp calling, requesting WhatsApp verification, and releasing the number all return 409.' }
|
|
32482
32486
|
profileId: { type: object }
|
|
32483
32487
|
provisionedAt: { type: string, format: date-time }
|
|
32484
32488
|
metaPreverifiedId: { type: string }
|
|
@@ -34376,6 +34380,7 @@ paths:
|
|
|
34376
34380
|
ivrOptions: { type: array, items: { type: object, properties: { digit: { type: string }, forwardTo: { type: string }, label: { type: string } } } }
|
|
34377
34381
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
34378
34382
|
'404': { description: Number not found }
|
|
34383
|
+
'409': { description: 'This number is attached to a SIP trunk; detach it first (code invalid_resource_state).' }
|
|
34379
34384
|
'422': { description: "This number is hosted by your own carrier (brought via WhatsApp embedded signup), so calls can't be enabled on it." }
|
|
34380
34385
|
delete:
|
|
34381
34386
|
x-resource-group: "telephony"
|
|
@@ -34402,6 +34407,266 @@ paths:
|
|
|
34402
34407
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
34403
34408
|
'404': { description: Number not found }
|
|
34404
34409
|
|
|
34410
|
+
/v1/phone-numbers/sip-trunks:
|
|
34411
|
+
post:
|
|
34412
|
+
x-resource-group: "telephony"
|
|
34413
|
+
operationId: createSipTrunk
|
|
34414
|
+
tags: [Voice]
|
|
34415
|
+
summary: Create a SIP trunk
|
|
34416
|
+
description: |
|
|
34417
|
+
Creates a SIP trunk an external voice platform (Retell, ElevenLabs,
|
|
34418
|
+
Vapi, or any SIP endpoint) can import your Zernio numbers into. The
|
|
34419
|
+
trunk carries both directions: inbound calls on attached numbers are
|
|
34420
|
+
delivered to `sipHost`, and the platform originates outbound calls
|
|
34421
|
+
through `termination.uri` with the digest credentials.
|
|
34422
|
+
|
|
34423
|
+
The `digestPassword` is returned only by this call (and by
|
|
34424
|
+
rotate-credentials); store it immediately. Attach any number of numbers
|
|
34425
|
+
to a trunk. Several trunks may point at the same host — each carries its
|
|
34426
|
+
own credentials and spend cap, so separate destination workspaces (e.g.
|
|
34427
|
+
an agency's clients) stay isolated.
|
|
34428
|
+
|
|
34429
|
+
security:
|
|
34430
|
+
- bearerAuth: []
|
|
34431
|
+
requestBody:
|
|
34432
|
+
required: true
|
|
34433
|
+
content:
|
|
34434
|
+
application/json:
|
|
34435
|
+
schema:
|
|
34436
|
+
type: object
|
|
34437
|
+
required: [label, sipHost]
|
|
34438
|
+
properties:
|
|
34439
|
+
label: { type: string, maxLength: 80, description: Display name for the trunk. }
|
|
34440
|
+
sipHost: { type: string, description: 'Fully-qualified hostname inbound calls are delivered to (e.g. sip.rtc.elevenlabs.io, sip.retellai.com).' }
|
|
34441
|
+
sipPort: { type: integer, minimum: 1, maximum: 65535, description: 'Defaults to 5061 for tls, 5060 otherwise.' }
|
|
34442
|
+
transport: { type: string, enum: [tls, tcp, udp], description: 'Signaling transport toward sipHost. Default tls (with SRTP media).' }
|
|
34443
|
+
responses:
|
|
34444
|
+
'201':
|
|
34445
|
+
description: Trunk created. The digest password is shown only here and on rotate.
|
|
34446
|
+
content:
|
|
34447
|
+
application/json:
|
|
34448
|
+
schema:
|
|
34449
|
+
type: object
|
|
34450
|
+
properties:
|
|
34451
|
+
id: { type: string }
|
|
34452
|
+
label: { type: string }
|
|
34453
|
+
sipHost: { type: string }
|
|
34454
|
+
sipPort: { type: integer }
|
|
34455
|
+
transport: { type: string, enum: [tls, tcp, udp] }
|
|
34456
|
+
termination:
|
|
34457
|
+
type: object
|
|
34458
|
+
properties:
|
|
34459
|
+
uri: { type: string, description: 'Telnyx termination host the platform dials for outbound (sip.telnyx.com).' }
|
|
34460
|
+
username: { type: string, description: SIP digest username. }
|
|
34461
|
+
numbersAttached: { type: integer }
|
|
34462
|
+
createdAt: { type: [string, "null"], format: date-time }
|
|
34463
|
+
digestPassword: { type: string, description: 'SIP digest password, shown only in this response.' }
|
|
34464
|
+
'400': { $ref: '#/components/responses/BadRequest' }
|
|
34465
|
+
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
34466
|
+
'403': { description: 'SIP trunking is not enabled for this workspace, or the workspace is on legacy (non-usage-based) billing, which cannot invoice trunk call costs (code feature_not_available).' }
|
|
34467
|
+
'409': { description: 'The workspace trunk limit was reached (code invalid_resource_state).' }
|
|
34468
|
+
'422': { description: 'The host cannot be used as a trunk destination (e.g. a Zernio or carrier host).' }
|
|
34469
|
+
get:
|
|
34470
|
+
x-resource-group: "telephony"
|
|
34471
|
+
operationId: listSipTrunks
|
|
34472
|
+
tags: [Voice]
|
|
34473
|
+
summary: List SIP trunks
|
|
34474
|
+
security:
|
|
34475
|
+
- bearerAuth: []
|
|
34476
|
+
responses:
|
|
34477
|
+
'200':
|
|
34478
|
+
description: The workspace's trunks. Passwords are never included.
|
|
34479
|
+
content:
|
|
34480
|
+
application/json:
|
|
34481
|
+
schema:
|
|
34482
|
+
type: object
|
|
34483
|
+
properties:
|
|
34484
|
+
trunks:
|
|
34485
|
+
type: array
|
|
34486
|
+
items:
|
|
34487
|
+
type: object
|
|
34488
|
+
properties:
|
|
34489
|
+
id: { type: string }
|
|
34490
|
+
label: { type: string }
|
|
34491
|
+
sipHost: { type: string }
|
|
34492
|
+
sipPort: { type: integer }
|
|
34493
|
+
transport: { type: string, enum: [tls, tcp, udp] }
|
|
34494
|
+
termination:
|
|
34495
|
+
type: object
|
|
34496
|
+
properties:
|
|
34497
|
+
uri: { type: string }
|
|
34498
|
+
username: { type: string }
|
|
34499
|
+
numbersAttached: { type: integer }
|
|
34500
|
+
createdAt: { type: [string, "null"], format: date-time }
|
|
34501
|
+
enabled: { type: boolean, description: 'Whether this workspace can create SIP trunks. Managing existing trunks always works.' }
|
|
34502
|
+
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
34503
|
+
|
|
34504
|
+
/v1/phone-numbers/sip-trunks/{id}:
|
|
34505
|
+
get:
|
|
34506
|
+
x-resource-group: "telephony"
|
|
34507
|
+
operationId: getSipTrunk
|
|
34508
|
+
tags: [Voice]
|
|
34509
|
+
summary: Get a SIP trunk
|
|
34510
|
+
security:
|
|
34511
|
+
- bearerAuth: []
|
|
34512
|
+
parameters:
|
|
34513
|
+
- { name: id, in: path, required: true, schema: { type: string } }
|
|
34514
|
+
responses:
|
|
34515
|
+
'200':
|
|
34516
|
+
description: Trunk detail, including the attached numbers.
|
|
34517
|
+
content:
|
|
34518
|
+
application/json:
|
|
34519
|
+
schema:
|
|
34520
|
+
type: object
|
|
34521
|
+
properties:
|
|
34522
|
+
id: { type: string }
|
|
34523
|
+
label: { type: string }
|
|
34524
|
+
sipHost: { type: string }
|
|
34525
|
+
sipPort: { type: integer }
|
|
34526
|
+
transport: { type: string, enum: [tls, tcp, udp] }
|
|
34527
|
+
termination:
|
|
34528
|
+
type: object
|
|
34529
|
+
properties:
|
|
34530
|
+
uri: { type: string }
|
|
34531
|
+
username: { type: string }
|
|
34532
|
+
numbersAttached: { type: integer }
|
|
34533
|
+
createdAt: { type: [string, "null"], format: date-time }
|
|
34534
|
+
numbers:
|
|
34535
|
+
type: array
|
|
34536
|
+
items:
|
|
34537
|
+
type: object
|
|
34538
|
+
properties:
|
|
34539
|
+
id: { type: string, description: 'Phone number record ID.' }
|
|
34540
|
+
phoneNumber: { type: string }
|
|
34541
|
+
'400': { $ref: '#/components/responses/BadRequest' }
|
|
34542
|
+
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
34543
|
+
'404': { description: SIP trunk not found }
|
|
34544
|
+
delete:
|
|
34545
|
+
x-resource-group: "telephony"
|
|
34546
|
+
operationId: deleteSipTrunk
|
|
34547
|
+
tags: [Voice]
|
|
34548
|
+
summary: Delete a SIP trunk
|
|
34549
|
+
description: |
|
|
34550
|
+
Tears down the trunk and its carrier-side objects. Refused while any
|
|
34551
|
+
number is still attached: detach them first.
|
|
34552
|
+
security:
|
|
34553
|
+
- bearerAuth: []
|
|
34554
|
+
parameters:
|
|
34555
|
+
- { name: id, in: path, required: true, schema: { type: string } }
|
|
34556
|
+
responses:
|
|
34557
|
+
'200':
|
|
34558
|
+
description: Trunk deleted.
|
|
34559
|
+
content:
|
|
34560
|
+
application/json:
|
|
34561
|
+
schema:
|
|
34562
|
+
type: object
|
|
34563
|
+
properties:
|
|
34564
|
+
deleted: { type: boolean }
|
|
34565
|
+
'400': { $ref: '#/components/responses/BadRequest' }
|
|
34566
|
+
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
34567
|
+
'404': { description: SIP trunk not found }
|
|
34568
|
+
'409': { description: 'Numbers are still attached to this trunk (code invalid_resource_state).' }
|
|
34569
|
+
|
|
34570
|
+
/v1/phone-numbers/sip-trunks/{id}/rotate-credentials:
|
|
34571
|
+
post:
|
|
34572
|
+
x-resource-group: "telephony"
|
|
34573
|
+
operationId: rotateSipTrunkCredentials
|
|
34574
|
+
tags: [Voice]
|
|
34575
|
+
summary: Rotate a SIP trunk's password
|
|
34576
|
+
description: |
|
|
34577
|
+
Mints a new digest password on the trunk. The old password stops
|
|
34578
|
+
working immediately, so update the destination platform right away.
|
|
34579
|
+
security:
|
|
34580
|
+
- bearerAuth: []
|
|
34581
|
+
parameters:
|
|
34582
|
+
- { name: id, in: path, required: true, schema: { type: string } }
|
|
34583
|
+
responses:
|
|
34584
|
+
'200':
|
|
34585
|
+
description: New credentials. The password is shown only here.
|
|
34586
|
+
content:
|
|
34587
|
+
application/json:
|
|
34588
|
+
schema:
|
|
34589
|
+
type: object
|
|
34590
|
+
properties:
|
|
34591
|
+
termination:
|
|
34592
|
+
type: object
|
|
34593
|
+
properties:
|
|
34594
|
+
uri: { type: string, description: 'Telnyx termination host the platform dials for outbound (sip.telnyx.com).' }
|
|
34595
|
+
username: { type: string, description: SIP digest username. }
|
|
34596
|
+
digestPassword: { type: string }
|
|
34597
|
+
'400': { $ref: '#/components/responses/BadRequest' }
|
|
34598
|
+
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
34599
|
+
'404': { description: SIP trunk not found }
|
|
34600
|
+
|
|
34601
|
+
/v1/phone-numbers/{id}/sip-trunk:
|
|
34602
|
+
post:
|
|
34603
|
+
x-resource-group: "telephony"
|
|
34604
|
+
operationId: attachNumberToSipTrunk
|
|
34605
|
+
tags: [Voice]
|
|
34606
|
+
summary: Attach a number to a SIP trunk
|
|
34607
|
+
description: |
|
|
34608
|
+
Routes the number's calls to the trunk: the external platform receives
|
|
34609
|
+
its inbound directly and can present it as outbound caller ID. While
|
|
34610
|
+
attached, Zernio-side voice features are off for this number (call
|
|
34611
|
+
forwarding, IVR, voicemail, recording, the softphone, and WhatsApp
|
|
34612
|
+
calling), so the number must have Calls and WhatsApp calling disabled
|
|
34613
|
+
before attaching. SMS and WhatsApp messaging are unaffected.
|
|
34614
|
+
security:
|
|
34615
|
+
- bearerAuth: []
|
|
34616
|
+
parameters:
|
|
34617
|
+
- { name: id, in: path, required: true, schema: { type: string }, description: "Phone number record ID (from GET /v1/phone-numbers)." }
|
|
34618
|
+
requestBody:
|
|
34619
|
+
required: true
|
|
34620
|
+
content:
|
|
34621
|
+
application/json:
|
|
34622
|
+
schema:
|
|
34623
|
+
type: object
|
|
34624
|
+
required: [trunkId]
|
|
34625
|
+
properties:
|
|
34626
|
+
trunkId: { type: string, description: 'SIP trunk ID (from POST /v1/phone-numbers/sip-trunks).' }
|
|
34627
|
+
responses:
|
|
34628
|
+
'200':
|
|
34629
|
+
description: Number attached (idempotent for the same trunk).
|
|
34630
|
+
content:
|
|
34631
|
+
application/json:
|
|
34632
|
+
schema:
|
|
34633
|
+
type: object
|
|
34634
|
+
properties:
|
|
34635
|
+
attached: { type: boolean }
|
|
34636
|
+
phoneNumber: { type: string }
|
|
34637
|
+
trunkId: { type: string }
|
|
34638
|
+
'400': { $ref: '#/components/responses/BadRequest' }
|
|
34639
|
+
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
34640
|
+
'403': { description: 'SIP trunking is not enabled for this workspace, or the workspace is on legacy (non-usage-based) billing, which cannot invoice trunk call costs (code feature_not_available).' }
|
|
34641
|
+
'404': { description: Number or trunk not found }
|
|
34642
|
+
'409': { description: 'The number still has Calls or WhatsApp calling enabled, is mid WhatsApp verification, is not active, or is attached to another trunk (code invalid_resource_state).' }
|
|
34643
|
+
'422': { description: 'This number is hosted by your own carrier (brought via WhatsApp embedded signup), so it cannot be trunked.' }
|
|
34644
|
+
delete:
|
|
34645
|
+
x-resource-group: "telephony"
|
|
34646
|
+
operationId: detachNumberFromSipTrunk
|
|
34647
|
+
tags: [Voice]
|
|
34648
|
+
summary: Detach a number from its SIP trunk
|
|
34649
|
+
description: |
|
|
34650
|
+
Returns the number's calls to Zernio routing. Idempotent when the
|
|
34651
|
+
number is not attached to any trunk.
|
|
34652
|
+
security:
|
|
34653
|
+
- bearerAuth: []
|
|
34654
|
+
parameters:
|
|
34655
|
+
- { name: id, in: path, required: true, schema: { type: string } }
|
|
34656
|
+
responses:
|
|
34657
|
+
'200':
|
|
34658
|
+
description: Number detached.
|
|
34659
|
+
content:
|
|
34660
|
+
application/json:
|
|
34661
|
+
schema:
|
|
34662
|
+
type: object
|
|
34663
|
+
properties:
|
|
34664
|
+
attached: { type: boolean, description: Always false after a successful detach. }
|
|
34665
|
+
phoneNumber: { type: string }
|
|
34666
|
+
'400': { $ref: '#/components/responses/BadRequest' }
|
|
34667
|
+
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
34668
|
+
'404': { description: Number not found }
|
|
34669
|
+
|
|
34405
34670
|
/v1/phone-numbers/{id}/sms:
|
|
34406
34671
|
post:
|
|
34407
34672
|
x-resource-group: "telephony"
|
|
@@ -34615,6 +34880,7 @@ paths:
|
|
|
34615
34880
|
'400': { description: 'Invalid request (including forwardTo set to the number itself)' }
|
|
34616
34881
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
34617
34882
|
'404': { description: Phone number not found }
|
|
34883
|
+
'409': { description: 'This number is attached to a SIP trunk; detach it first (code invalid_resource_state).' }
|
|
34618
34884
|
'422': { description: "Not eligible to enable calling: not on usage-based billing, or the number's messaging limit is below Meta's ~2,000-daily-recipient threshold (TIER_250). Warm the number up to raise the limit." }
|
|
34619
34885
|
patch:
|
|
34620
34886
|
x-resource-group: "telephony"
|
|
@@ -34802,6 +35068,7 @@ paths:
|
|
|
34802
35068
|
endUserLastName: { type: [string, "null"] }
|
|
34803
35069
|
regulatoryDeclineReason: { type: [string, "null"], description: Reviewer rejection reason when status is regulatory_declined. }
|
|
34804
35070
|
provisionedAt: { type: string, format: date-time }
|
|
35071
|
+
sipTrunkId: { type: [string, "null"], description: 'SIP trunk the number is attached to; null when not trunked. While attached, enabling Calls or WhatsApp calling, requesting WhatsApp verification, and releasing the number all return 409.' }
|
|
34805
35072
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
34806
35073
|
'404': { $ref: '#/components/responses/NotFound' }
|
|
34807
35074
|
delete:
|
|
@@ -34847,6 +35114,7 @@ paths:
|
|
|
34847
35114
|
'400': { description: Phone number is already released or being released }
|
|
34848
35115
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
34849
35116
|
'404': { $ref: '#/components/responses/NotFound' }
|
|
35117
|
+
'409': { description: 'The number is attached to a SIP trunk; detach it first (code invalid_resource_state).' }
|
|
34850
35118
|
|
|
34851
35119
|
# ─── WhatsApp Sandbox (shared test number) ──────────────────────
|
|
34852
35120
|
#
|
data/spec/api/posts_api_spec.rb
CHANGED
|
@@ -47,7 +47,7 @@ describe 'PostsApi' do
|
|
|
47
47
|
|
|
48
48
|
# unit tests for create_post
|
|
49
49
|
# Create post
|
|
50
|
-
# Create and optionally publish a post. Immediate posts (`publishNow: true`) include `platformPostUrl` in the response. Content is optional when media is attached, all platforms have `customContent`, every platform entry is an X Article (`platformSpecificData.article`), or every platform entry is a LinkedIn
|
|
50
|
+
# Create and optionally publish a post. Immediate posts (`publishNow: true`) include `platformPostUrl` in the response. Content is optional when media is attached, all platforms have `customContent`, every platform entry is an X Article (`platformSpecificData.article`), or every platform entry is a LinkedIn text-free reshare (`platformSpecificData.reshareUrl` with no text). See each platform's schema for media constraints. ## Idempotency Two layers of duplicate-protection apply, so safe-to-retry callers (network blips, n8n / Zapier retries, etc.) don't accidentally double-post. **1. Same-request idempotency (5-minute window).** Pass an `x-request-id` header to mark a logical request. If a second request arrives with the same `x-request-id` while the first is in-flight (or within ~5 minutes of completion), we return **HTTP 200** with the original post in the `existingPost` field — no new post is created. The official Zernio SDKs auto-generate a unique `x-request-id` per call. If you're using a generic HTTP client (curl, n8n's HTTP node, Zapier, custom code), either: - Set a unique `x-request-id` per logical call (recommended — UUIDv4 is fine) - Or simply omit the header — we'll treat each request as new **Common pitfall**: if your workflow tool uses a single execution-level request ID and reuses it across multiple HTTP nodes (e.g. one ID for the whole run, shared across 6 different platform calls), every call after the first will look like a retry of the first and return its post. Generate a fresh ID per node. **2. Content-hash dedup (24-hour window).** Independently, we hash `(platform, accountId, content + media URLs)` and reject duplicates within 24 hours with **HTTP 409**. This catches genuine \"same content posted twice to the same account\" cases regardless of `x-request-id`. Returns `error`, `accountId`, `platform`, and `existingPostId` so you can find the original. To intentionally re-post identical content within 24h, change something (the caption, the media, the account) — the dedup is keyed on the full content fingerprint. Order: same-`x-request-id` retries (200) are checked first; if no idempotency match, the content-hash dedup (409) runs.
|
|
51
51
|
# @param create_post_request
|
|
52
52
|
# @param [Hash] opts the optional parameters
|
|
53
53
|
# @option opts [String] :x_request_id Optional client-generated request identifier for safe retry (idempotency). When two requests carry the same value, the second is treated as a retry of the first and returns the original post (HTTP 200) instead of creating a duplicate. Window is ~5 minutes from the first request. Generate a UUID per logical call. SDKs do this automatically; HTTP clients should set it themselves or omit it. See the operation description for the full idempotency contract.
|
data/spec/api/voice_api_spec.rb
CHANGED
|
@@ -32,6 +32,31 @@ describe 'VoiceApi' do
|
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
+
# unit tests for attach_number_to_sip_trunk
|
|
36
|
+
# Attach a number to a SIP trunk
|
|
37
|
+
# Routes the number's calls to the trunk: the external platform receives its inbound directly and can present it as outbound caller ID. While attached, Zernio-side voice features are off for this number (call forwarding, IVR, voicemail, recording, the softphone, and WhatsApp calling), so the number must have Calls and WhatsApp calling disabled before attaching. SMS and WhatsApp messaging are unaffected.
|
|
38
|
+
# @param id Phone number record ID (from GET /v1/phone-numbers).
|
|
39
|
+
# @param attach_number_to_sip_trunk_request
|
|
40
|
+
# @param [Hash] opts the optional parameters
|
|
41
|
+
# @return [AttachNumberToSipTrunk200Response]
|
|
42
|
+
describe 'attach_number_to_sip_trunk test' do
|
|
43
|
+
it 'should work' do
|
|
44
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# unit tests for create_sip_trunk
|
|
49
|
+
# Create a SIP trunk
|
|
50
|
+
# Creates a SIP trunk an external voice platform (Retell, ElevenLabs, Vapi, or any SIP endpoint) can import your Zernio numbers into. The trunk carries both directions: inbound calls on attached numbers are delivered to `sipHost`, and the platform originates outbound calls through `termination.uri` with the digest credentials. The `digestPassword` is returned only by this call (and by rotate-credentials); store it immediately. Attach any number of numbers to a trunk. Several trunks may point at the same host — each carries its own credentials and spend cap, so separate destination workspaces (e.g. an agency's clients) stay isolated.
|
|
51
|
+
# @param create_sip_trunk_request
|
|
52
|
+
# @param [Hash] opts the optional parameters
|
|
53
|
+
# @return [CreateSipTrunk201Response]
|
|
54
|
+
describe 'create_sip_trunk test' do
|
|
55
|
+
it 'should work' do
|
|
56
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
35
60
|
# unit tests for create_voice_call
|
|
36
61
|
# Place an outbound phone call
|
|
37
62
|
# Dials `to` FROM one of your voice-enabled numbers and, on answer, bridges the callee to the number's stored forward destination, or to the per-call `forwardTo` override. Destinations can be your own AI voice agent (Vapi/Retell), a phone, or a SIP endpoint. An optional `greeting` is spoken to the callee before the bridge. The 200 response means the call is dialing; the lifecycle continues asynchronously (track it via `GET /v1/voice/calls/{id}` or the `call.*` webhooks). Outbound calls are capped per rolling hour (429 when hit). **Idempotency:** send an `Idempotency-Key` header to make retries safe; same key + same body replays the original response instead of dialing (and billing) a second call.
|
|
@@ -56,6 +81,30 @@ describe 'VoiceApi' do
|
|
|
56
81
|
end
|
|
57
82
|
end
|
|
58
83
|
|
|
84
|
+
# unit tests for delete_sip_trunk
|
|
85
|
+
# Delete a SIP trunk
|
|
86
|
+
# Tears down the trunk and its carrier-side objects. Refused while any number is still attached: detach them first.
|
|
87
|
+
# @param id
|
|
88
|
+
# @param [Hash] opts the optional parameters
|
|
89
|
+
# @return [DeleteSmsSenderId200Response]
|
|
90
|
+
describe 'delete_sip_trunk test' do
|
|
91
|
+
it 'should work' do
|
|
92
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# unit tests for detach_number_from_sip_trunk
|
|
97
|
+
# Detach a number from its SIP trunk
|
|
98
|
+
# Returns the number's calls to Zernio routing. Idempotent when the number is not attached to any trunk.
|
|
99
|
+
# @param id
|
|
100
|
+
# @param [Hash] opts the optional parameters
|
|
101
|
+
# @return [DetachNumberFromSipTrunk200Response]
|
|
102
|
+
describe 'detach_number_from_sip_trunk test' do
|
|
103
|
+
it 'should work' do
|
|
104
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
59
108
|
# unit tests for dial_voice_web_call
|
|
60
109
|
# Dial from the browser softphone
|
|
61
110
|
# Step 2 of the browser softphone handshake: places an outbound call whose answered leg is bridged to the browser registered with the credential from `POST /v1/voice/calls/web`. The call runs through the normal outbound lane, so it is logged as outbound (from = your number, to = target) and recorded per the number's settings.
|
|
@@ -105,6 +154,17 @@ describe 'VoiceApi' do
|
|
|
105
154
|
end
|
|
106
155
|
end
|
|
107
156
|
|
|
157
|
+
# unit tests for get_sip_trunk
|
|
158
|
+
# Get a SIP trunk
|
|
159
|
+
# @param id
|
|
160
|
+
# @param [Hash] opts the optional parameters
|
|
161
|
+
# @return [GetSipTrunk200Response]
|
|
162
|
+
describe 'get_sip_trunk test' do
|
|
163
|
+
it 'should work' do
|
|
164
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
108
168
|
# unit tests for get_voice_call
|
|
109
169
|
# Get a phone call
|
|
110
170
|
# Full call detail, including the transcript segments when transcription was on.
|
|
@@ -145,6 +205,16 @@ describe 'VoiceApi' do
|
|
|
145
205
|
end
|
|
146
206
|
end
|
|
147
207
|
|
|
208
|
+
# unit tests for list_sip_trunks
|
|
209
|
+
# List SIP trunks
|
|
210
|
+
# @param [Hash] opts the optional parameters
|
|
211
|
+
# @return [ListSipTrunks200Response]
|
|
212
|
+
describe 'list_sip_trunks test' do
|
|
213
|
+
it 'should work' do
|
|
214
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
148
218
|
# unit tests for list_voice_calls
|
|
149
219
|
# List phone calls
|
|
150
220
|
# Your PSTN voice calls (inbound + outbound), newest first. Cursor pagination: pass the returned `nextCursor` as `before` for the next page. For a history that also includes WhatsApp calls, use `GET /v1/calls`.
|
|
@@ -161,6 +231,18 @@ describe 'VoiceApi' do
|
|
|
161
231
|
end
|
|
162
232
|
end
|
|
163
233
|
|
|
234
|
+
# unit tests for rotate_sip_trunk_credentials
|
|
235
|
+
# Rotate a SIP trunk's password
|
|
236
|
+
# Mints a new digest password on the trunk. The old password stops working immediately, so update the destination platform right away.
|
|
237
|
+
# @param id
|
|
238
|
+
# @param [Hash] opts the optional parameters
|
|
239
|
+
# @return [RotateSipTrunkCredentials200Response]
|
|
240
|
+
describe 'rotate_sip_trunk_credentials test' do
|
|
241
|
+
it 'should work' do
|
|
242
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
164
246
|
# unit tests for transfer_voice_call
|
|
165
247
|
# Blind-transfer a live call
|
|
166
248
|
# Moves the call's current leg to a new destination (a phone number or a SIP endpoint). This is a BLIND transfer: control of the leg is handed off and the call ends normally when the transferred leg hangs up. The caller ID presented on the transfer leg is always your own number.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#Zernio API
|
|
3
|
+
|
|
4
|
+
#API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.4
|
|
7
|
+
Contact: support@zernio.com
|
|
8
|
+
Generated by: https://openapi-generator.tech
|
|
9
|
+
Generator version: 7.19.0
|
|
10
|
+
|
|
11
|
+
=end
|
|
12
|
+
|
|
13
|
+
require 'spec_helper'
|
|
14
|
+
require 'json'
|
|
15
|
+
require 'date'
|
|
16
|
+
|
|
17
|
+
# Unit tests for Zernio::AttachNumberToSipTrunk200Response
|
|
18
|
+
# Automatically generated by openapi-generator (https://openapi-generator.tech)
|
|
19
|
+
# Please update as you see appropriate
|
|
20
|
+
describe Zernio::AttachNumberToSipTrunk200Response do
|
|
21
|
+
#let(:instance) { Zernio::AttachNumberToSipTrunk200Response.new }
|
|
22
|
+
|
|
23
|
+
describe 'test an instance of AttachNumberToSipTrunk200Response' do
|
|
24
|
+
it 'should create an instance of AttachNumberToSipTrunk200Response' do
|
|
25
|
+
# uncomment below to test the instance creation
|
|
26
|
+
#expect(instance).to be_instance_of(Zernio::AttachNumberToSipTrunk200Response)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'test attribute "attached"' do
|
|
31
|
+
it 'should work' do
|
|
32
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe 'test attribute "phone_number"' do
|
|
37
|
+
it 'should work' do
|
|
38
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe 'test attribute "trunk_id"' do
|
|
43
|
+
it 'should work' do
|
|
44
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#Zernio API
|
|
3
|
+
|
|
4
|
+
#API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.4
|
|
7
|
+
Contact: support@zernio.com
|
|
8
|
+
Generated by: https://openapi-generator.tech
|
|
9
|
+
Generator version: 7.19.0
|
|
10
|
+
|
|
11
|
+
=end
|
|
12
|
+
|
|
13
|
+
require 'spec_helper'
|
|
14
|
+
require 'json'
|
|
15
|
+
require 'date'
|
|
16
|
+
|
|
17
|
+
# Unit tests for Zernio::AttachNumberToSipTrunkRequest
|
|
18
|
+
# Automatically generated by openapi-generator (https://openapi-generator.tech)
|
|
19
|
+
# Please update as you see appropriate
|
|
20
|
+
describe Zernio::AttachNumberToSipTrunkRequest do
|
|
21
|
+
#let(:instance) { Zernio::AttachNumberToSipTrunkRequest.new }
|
|
22
|
+
|
|
23
|
+
describe 'test an instance of AttachNumberToSipTrunkRequest' do
|
|
24
|
+
it 'should create an instance of AttachNumberToSipTrunkRequest' do
|
|
25
|
+
# uncomment below to test the instance creation
|
|
26
|
+
#expect(instance).to be_instance_of(Zernio::AttachNumberToSipTrunkRequest)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'test attribute "trunk_id"' do
|
|
31
|
+
it 'should work' do
|
|
32
|
+
# assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|