zernio-sdk 0.0.539 → 0.0.541

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.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -42
  3. data/docs/AdAudiencesApi.md +5 -5
  4. data/docs/AdCampaignsApi.md +0 -142
  5. data/docs/AdsApi.md +18 -700
  6. data/docs/InboxApi.md +79 -0
  7. data/docs/InboxWebhookMessageAttachmentsInner.md +1 -1
  8. data/docs/SMSApi.md +1 -276
  9. data/docs/SendSmsRequest.md +1 -1
  10. data/docs/WebhookPayloadMessageMessage.md +1 -1
  11. data/docs/WebhookPayloadMessageMessageAttachmentsInner.md +22 -0
  12. data/docs/WebhookPayloadMessageSentMessage.md +1 -1
  13. data/docs/WebhookPayloadMessageSentMessageAttachmentsInner.md +22 -0
  14. data/lib/zernio-sdk/api/ad_audiences_api.rb +4 -4
  15. data/lib/zernio-sdk/api/ad_campaigns_api.rb +0 -142
  16. data/lib/zernio-sdk/api/ads_api.rb +39 -739
  17. data/lib/zernio-sdk/api/inbox_api.rb +92 -0
  18. data/lib/zernio-sdk/api/sms_api.rb +2 -256
  19. data/lib/zernio-sdk/models/inbox_webhook_message_attachments_inner.rb +1 -1
  20. data/lib/zernio-sdk/models/send_sms_request.rb +1 -1
  21. data/lib/zernio-sdk/models/webhook_payload_message_message.rb +1 -1
  22. data/lib/zernio-sdk/models/{create_sms_sender_id_request.rb → webhook_payload_message_message_attachments_inner.rb} +52 -33
  23. data/lib/zernio-sdk/models/webhook_payload_message_sent_message.rb +1 -1
  24. data/lib/zernio-sdk/models/{update_ad_creative_request.rb → webhook_payload_message_sent_message_attachments_inner.rb} +46 -44
  25. data/lib/zernio-sdk/version.rb +1 -1
  26. data/lib/zernio-sdk.rb +3 -26
  27. data/openapi.yaml +87 -624
  28. data/spec/api/ad_audiences_api_spec.rb +2 -2
  29. data/spec/api/ad_campaigns_api_spec.rb +0 -25
  30. data/spec/api/ads_api_spec.rb +0 -128
  31. data/spec/api/inbox_api_spec.rb +48 -0
  32. data/spec/api/sms_api_spec.rb +1 -47
  33. data/spec/models/{list_ad_images200_response_spec.rb → webhook_payload_message_message_attachments_inner_spec.rb} +9 -9
  34. data/spec/models/{list_ad_creatives200_response_spec.rb → webhook_payload_message_sent_message_attachments_inner_spec.rb} +9 -9
  35. metadata +13 -105
  36. data/docs/CreateAdCampaign201Response.md +0 -24
  37. data/docs/CreateAdCampaignRequest.md +0 -32
  38. data/docs/CreateAdCreative201Response.md +0 -20
  39. data/docs/CreateAdCreativeRequest.md +0 -38
  40. data/docs/CreateAdCreativeRequestCarouselCardsInner.md +0 -26
  41. data/docs/CreateSmsSenderId200Response.md +0 -22
  42. data/docs/CreateSmsSenderIdRequest.md +0 -18
  43. data/docs/DeleteAdCreative200Response.md +0 -20
  44. data/docs/DeleteSmsSenderId200Response.md +0 -18
  45. data/docs/DuplicateAd200Response.md +0 -22
  46. data/docs/DuplicateAdRequest.md +0 -28
  47. data/docs/DuplicateAdSet200Response.md +0 -22
  48. data/docs/DuplicateAdSetRequest.md +0 -36
  49. data/docs/GetAdCreative200Response.md +0 -18
  50. data/docs/ListAdCreatives200Response.md +0 -22
  51. data/docs/ListAdImages200Response.md +0 -22
  52. data/docs/ListAdLabels200Response.md +0 -22
  53. data/docs/ListHighDemandPeriods200Response.md +0 -22
  54. data/docs/ListSmsSenderIds200Response.md +0 -20
  55. data/docs/ListSmsSenderIds200ResponseBudget.md +0 -24
  56. data/docs/ListSmsSenderIds200ResponseBudgetPendingRequest.md +0 -22
  57. data/docs/ListSmsSenderIds200ResponseSenderIdsInner.md +0 -24
  58. data/docs/RequestSmsSenderIdLimitIncrease200Response.md +0 -20
  59. data/docs/RequestSmsSenderIdLimitIncreaseRequest.md +0 -20
  60. data/docs/UpdateAdCreative200Response.md +0 -22
  61. data/docs/UpdateAdCreativeRequest.md +0 -20
  62. data/lib/zernio-sdk/models/create_ad_campaign201_response.rb +0 -210
  63. data/lib/zernio-sdk/models/create_ad_campaign_request.rb +0 -343
  64. data/lib/zernio-sdk/models/create_ad_creative201_response.rb +0 -157
  65. data/lib/zernio-sdk/models/create_ad_creative_request.rb +0 -390
  66. data/lib/zernio-sdk/models/create_ad_creative_request_carousel_cards_inner.rb +0 -255
  67. data/lib/zernio-sdk/models/create_sms_sender_id200_response.rb +0 -166
  68. data/lib/zernio-sdk/models/delete_ad_creative200_response.rb +0 -156
  69. data/lib/zernio-sdk/models/delete_sms_sender_id200_response.rb +0 -147
  70. data/lib/zernio-sdk/models/duplicate_ad200_response.rb +0 -200
  71. data/lib/zernio-sdk/models/duplicate_ad_request.rb +0 -243
  72. data/lib/zernio-sdk/models/duplicate_ad_set200_response.rb +0 -201
  73. data/lib/zernio-sdk/models/duplicate_ad_set_request.rb +0 -302
  74. data/lib/zernio-sdk/models/get_ad_creative200_response.rb +0 -148
  75. data/lib/zernio-sdk/models/list_ad_creatives200_response.rb +0 -167
  76. data/lib/zernio-sdk/models/list_ad_images200_response.rb +0 -167
  77. data/lib/zernio-sdk/models/list_ad_labels200_response.rb +0 -167
  78. data/lib/zernio-sdk/models/list_high_demand_periods200_response.rb +0 -168
  79. data/lib/zernio-sdk/models/list_sms_sender_ids200_response.rb +0 -158
  80. data/lib/zernio-sdk/models/list_sms_sender_ids200_response_budget.rb +0 -178
  81. data/lib/zernio-sdk/models/list_sms_sender_ids200_response_budget_pending_request.rb +0 -167
  82. data/lib/zernio-sdk/models/list_sms_sender_ids200_response_sender_ids_inner.rb +0 -175
  83. data/lib/zernio-sdk/models/request_sms_sender_id_limit_increase200_response.rb +0 -156
  84. data/lib/zernio-sdk/models/request_sms_sender_id_limit_increase_request.rb +0 -210
  85. data/lib/zernio-sdk/models/update_ad_creative200_response.rb +0 -165
  86. data/spec/models/create_ad_campaign201_response_spec.rb +0 -58
  87. data/spec/models/create_ad_campaign_request_spec.rb +0 -94
  88. data/spec/models/create_ad_creative201_response_spec.rb +0 -42
  89. data/spec/models/create_ad_creative_request_carousel_cards_inner_spec.rb +0 -60
  90. data/spec/models/create_ad_creative_request_spec.rb +0 -96
  91. data/spec/models/create_sms_sender_id200_response_spec.rb +0 -48
  92. data/spec/models/create_sms_sender_id_request_spec.rb +0 -36
  93. data/spec/models/delete_ad_creative200_response_spec.rb +0 -42
  94. data/spec/models/delete_sms_sender_id200_response_spec.rb +0 -36
  95. data/spec/models/duplicate_ad200_response_spec.rb +0 -52
  96. data/spec/models/duplicate_ad_request_spec.rb +0 -74
  97. data/spec/models/duplicate_ad_set200_response_spec.rb +0 -52
  98. data/spec/models/duplicate_ad_set_request_spec.rb +0 -102
  99. data/spec/models/get_ad_creative200_response_spec.rb +0 -36
  100. data/spec/models/list_ad_labels200_response_spec.rb +0 -48
  101. data/spec/models/list_high_demand_periods200_response_spec.rb +0 -48
  102. data/spec/models/list_sms_sender_ids200_response_budget_pending_request_spec.rb +0 -48
  103. data/spec/models/list_sms_sender_ids200_response_budget_spec.rb +0 -54
  104. data/spec/models/list_sms_sender_ids200_response_sender_ids_inner_spec.rb +0 -54
  105. data/spec/models/list_sms_sender_ids200_response_spec.rb +0 -42
  106. data/spec/models/request_sms_sender_id_limit_increase200_response_spec.rb +0 -42
  107. data/spec/models/request_sms_sender_id_limit_increase_request_spec.rb +0 -42
  108. data/spec/models/update_ad_creative200_response_spec.rb +0 -48
  109. data/spec/models/update_ad_creative_request_spec.rb +0 -42
data/openapi.yaml CHANGED
@@ -2664,7 +2664,13 @@ components:
2664
2664
  description: Attachment type (image, video, file, sticker, audio)
2665
2665
  url:
2666
2666
  type: string
2667
- description: Attachment URL (may expire for Meta platforms)
2667
+ description: |
2668
+ Where to fetch the attachment. The contract depends on direction and
2669
+ platform: inbound WhatsApp media points at the authenticated
2670
+ `GET /v1/whatsapp/media/{mediaId}` and requires
2671
+ `Authorization: Bearer <your API key>`, while outgoing media carries the
2672
+ URL originally supplied and Instagram / Facebook / Telegram carry direct
2673
+ platform CDN links that need no authentication.
2668
2674
  payload:
2669
2675
  type: object
2670
2676
  description: Additional attachment metadata
@@ -2878,7 +2884,19 @@ components:
2878
2884
  description: Attachment type (image, video, file, sticker, audio)
2879
2885
  url:
2880
2886
  type: string
2881
- description: Attachment URL (may expire for Meta platforms)
2887
+ description: |
2888
+ Where to fetch the attachment. **The contract differs by platform.**
2889
+
2890
+ - **WhatsApp**: points at `GET /v1/whatsapp/media/{mediaId}`, an
2891
+ authenticated Zernio endpoint. You MUST send
2892
+ `Authorization: Bearer <your API key>`; fetching it without that
2893
+ header returns `401`. Download and store the bytes when this
2894
+ webhook arrives: Meta drops inbound media after a limited
2895
+ retention window, after which the endpoint answers `400`
2896
+ permanently and the media is unrecoverable.
2897
+ - **Instagram / Facebook / Telegram**: a direct platform CDN link
2898
+ that needs no authentication and expires on the platform's own
2899
+ schedule.
2882
2900
  payload:
2883
2901
  type: object
2884
2902
  description: Additional attachment metadata
@@ -3190,7 +3208,13 @@ components:
3190
3208
  description: Attachment type (image, video, file, sticker, audio)
3191
3209
  url:
3192
3210
  type: string
3193
- description: Attachment URL (may expire for Meta platforms)
3211
+ description: |
3212
+ Where to fetch the attachment. For outgoing messages this is the
3213
+ media URL as sent, so for WhatsApp it is the URL you supplied when
3214
+ publishing (WhatsApp sends media by link), not a Zernio endpoint,
3215
+ and it needs no Zernio credentials. Contrast the inbound direction:
3216
+ `message.received` attachment URLs on WhatsApp point at the
3217
+ authenticated `GET /v1/whatsapp/media/{mediaId}`.
3194
3218
  payload:
3195
3219
  type: object
3196
3220
  description: Additional attachment metadata
@@ -9255,7 +9279,9 @@ paths:
9255
9279
  content:
9256
9280
  application/json:
9257
9281
  schema:
9258
- $ref: '#/components/schemas/ErrorResponse'
9282
+ type: object
9283
+ properties:
9284
+ error: { type: string }
9259
9285
  examples:
9260
9286
  invalidMetric:
9261
9287
  value:
@@ -11182,20 +11208,10 @@ paths:
11182
11208
  key: "temp/1234567890_abc123_my-video.mp4"
11183
11209
  expiresIn: 3600
11184
11210
  '400':
11185
- description: Invalid request (missing filename, contentType, or unsupported content type)
11211
+ description: 'Invalid request (missing filename, unsupported contentType, or size out of range)'
11186
11212
  content:
11187
11213
  application/json:
11188
- schema:
11189
- type: object
11190
- properties:
11191
- error: { type: string }
11192
- examples:
11193
- missing_filename:
11194
- value: { error: "Missing required fields: filename and contentType" }
11195
- invalid_type:
11196
- value: { error: "Content type not allowed: text/plain" }
11197
- file_too_large:
11198
- value: { error: "File too large. Maximum size is 5GB." }
11214
+ schema: { $ref: '#/components/schemas/ErrorResponse' }
11199
11215
  '401': { $ref: '#/components/responses/Unauthorized' }
11200
11216
  /v1/reddit/search:
11201
11217
  get:
@@ -22574,6 +22590,49 @@ paths:
22574
22590
  '403':
22575
22591
  description: Inbox addon required
22576
22592
 
22593
+ /v1/whatsapp/media/{mediaId}:
22594
+ get:
22595
+ operationId: getWhatsAppMedia
22596
+ tags: [Inbox]
22597
+ summary: Download WhatsApp media
22598
+ description: |
22599
+ Streams the binary for a WhatsApp attachment. This is the endpoint the
22600
+ `url` on a WhatsApp `attachments[]` entry points at, in both the
22601
+ `message.received` webhook and the List messages response.
22602
+
22603
+ **This is an authenticated endpoint, not a public link.** Send
22604
+ `Authorization: Bearer <your API key>` exactly as you would for any other
22605
+ call. Passing the URL straight to a browser, an LLM vision API, or a
22606
+ no-code "download file" step without the header returns `401`. This is
22607
+ the most common integration mistake on this endpoint, and it differs from
22608
+ Instagram, Facebook and Telegram, whose `attachments[].url` is a direct
22609
+ CDN link that needs no header.
22610
+
22611
+ **Fetch on receipt, not lazily.** WhatsApp media lives in Meta's media
22612
+ store, not ours, and it is removed after a limited retention window
22613
+ (currently 7 days, and Meta has been dropping some inbound media sooner).
22614
+ Once Meta drops it the media is unrecoverable and this endpoint answers
22615
+ `400` permanently, so retrying will never succeed. Download and store the
22616
+ bytes when the webhook arrives.
22617
+ security:
22618
+ - bearerAuth: []
22619
+ parameters:
22620
+ - { name: mediaId, in: path, required: true, schema: { type: string }, description: 'The media id from `attachments[].payload.id`.' }
22621
+ - { name: accountId, in: query, required: true, schema: { type: string }, description: 'The WhatsApp account that received the media.' }
22622
+ responses:
22623
+ '200':
22624
+ description: The media binary, streamed with its original content type.
22625
+ content:
22626
+ application/octet-stream:
22627
+ schema: { type: string, format: binary }
22628
+ '400':
22629
+ description: 'Media is no longer available on WhatsApp servers (expired or deleted by Meta). Permanent, do not retry.'
22630
+ '401': { $ref: '#/components/responses/Unauthorized' }
22631
+ '404':
22632
+ description: 'Account not found, not accessible to the caller, or the media does not belong to it.'
22633
+ '502':
22634
+ description: Meta could not be reached or returned an unexpected error.
22635
+
22577
22636
  /v1/inbox/conversations/{conversationId}/messages/{messageId}:
22578
22637
  patch:
22579
22638
  operationId: editInboxMessage
@@ -25737,19 +25796,13 @@ paths:
25737
25796
  summary: Send an SMS/MMS
25738
25797
  description: |
25739
25798
  Sends an SMS (or MMS when `mediaUrls` is set) from one of your
25740
- SMS-enabled numbers, or from an approved alphanumeric sender ID
25741
- (`/v1/sms/sender-ids`). At least one of `text` / `mediaUrls` is
25742
- required. Numbers are normalized to E.164, so `from` matches regardless
25743
- of formatting and replies thread into the same inbox conversation.
25799
+ SMS-enabled numbers. At least one of `text` / `mediaUrls` is required.
25800
+ Both numbers are normalized to E.164, so `from` matches regardless of
25801
+ formatting and replies thread into the same inbox conversation.
25744
25802
 
25745
25803
  US numbers must have an approved carrier registration
25746
25804
  (`/v1/sms/registrations`) before messages deliver.
25747
25805
 
25748
- **Alphanumeric sender IDs** are one-way and international only: they
25749
- cannot reach the US, Canada, or Puerto Rico (403), are text-only (no
25750
- MMS), and recipients cannot reply. Some destination countries
25751
- substitute a numeric sender to ensure delivery.
25752
-
25753
25806
  **Idempotency:** send an `Idempotency-Key` header to make retries safe:
25754
25807
  same key + same body replays the original response instead of sending a
25755
25808
  second message; same key + different body returns 422; a key still in
@@ -25773,7 +25826,7 @@ paths:
25773
25826
  type: object
25774
25827
  required: [from, to]
25775
25828
  properties:
25776
- from: { type: string, description: 'One of your SMS-enabled numbers (E.164; formatting is normalized), or an approved alphanumeric sender ID (3-11 letters/digits/spaces, created via `/v1/sms/sender-ids`).' }
25829
+ from: { type: string, description: One of your SMS-enabled numbers (E.164; formatting is normalized). }
25777
25830
  to: { type: string, description: Recipient number (E.164). }
25778
25831
  text: { type: string, description: "Message body. Required unless `mediaUrls` is set. Max 10 SMS segments (1530 GSM-7 or 670 unicode characters)." }
25779
25832
  mediaUrls:
@@ -25796,13 +25849,10 @@ paths:
25796
25849
  id: { type: string, description: Message ID }
25797
25850
  conversationId: { type: string, description: Inbox conversation the message was threaded into. }
25798
25851
  status: { type: string, enum: [sent] }
25799
- '400': { $ref: '#/components/responses/BadRequest' }
25800
25852
  '401': { $ref: '#/components/responses/Unauthorized' }
25801
- '403': { description: 'Send refused by a gate: US registration missing/pending, MMS not supported by this sender, or an alphanumeric sender ID addressed to the US, Canada or Puerto Rico.' }
25802
- '404': { description: "No SMS-enabled number or sender ID matches `from`" }
25853
+ '404': { description: "No SMS-enabled number matches `from`" }
25803
25854
  '409': { description: Same Idempotency-Key still processing; retry after a short backoff }
25804
25855
  '422': { description: Idempotency-Key reused with a different body }
25805
- '429': { description: 'Daily sender ID message limit reached for the workspace (alphanumeric sends only, code `alpha_daily_limit_reached`; resets midnight UTC, raisable via support).' }
25806
25856
  '502': { description: Carrier-side send failed }
25807
25857
 
25808
25858
  /v1/sms/lookup:
@@ -25872,155 +25922,6 @@ paths:
25872
25922
  schema: { type: string, description: "`format=csv` download. Columns: phone_number, opted_out_at, keyword, our_number" }
25873
25923
  '401': { $ref: '#/components/responses/Unauthorized' }
25874
25924
 
25875
- /v1/sms/sender-ids:
25876
- post:
25877
- operationId: createSmsSenderId
25878
- tags: [SMS]
25879
- summary: Create an alphanumeric sender ID
25880
- description: |
25881
- Registers an alphanumeric sender ID (e.g. `ZERNIO`) — a branded `from`
25882
- for one-way international SMS. No phone number purchase or carrier
25883
- registration is needed; once created, pass it as `from` on
25884
- `POST /v1/sms/messages`.
25885
-
25886
- Constraints: 3-11 characters (letters, digits, spaces; at least one
25887
- letter). Sends cannot reach the US, Canada, or Puerto Rico, are
25888
- text-only, and recipients cannot reply. Sender IDs that impersonate
25889
- well-known brands or institutions are rejected, and an ID already
25890
- registered by another workspace returns 409 (active sender IDs are
25891
- globally unique, first-come-first-served). Creating the same sender ID
25892
- again is a no-op (re-activates it after a delete).
25893
- security:
25894
- - bearerAuth: []
25895
- requestBody:
25896
- required: true
25897
- content:
25898
- application/json:
25899
- schema:
25900
- type: object
25901
- required: [senderId]
25902
- properties:
25903
- senderId:
25904
- type: string
25905
- minLength: 3
25906
- maxLength: 11
25907
- description: 'The sender ID recipients will see (3-11 letters/digits/spaces, at least one letter, no leading/trailing space).'
25908
- responses:
25909
- '200':
25910
- description: Sender ID created (or re-activated).
25911
- content:
25912
- application/json:
25913
- schema:
25914
- type: object
25915
- properties:
25916
- id: { type: string, description: Sender ID resource id. }
25917
- senderId: { type: string }
25918
- isActive: { type: boolean }
25919
- '400': { $ref: '#/components/responses/BadRequest' }
25920
- '401': { $ref: '#/components/responses/Unauthorized' }
25921
- '403': { description: 'Workspace is not on usage-based billing, or already holds the maximum of 5 active sender IDs (code `sender_id_limit_reached`; raisable via support).' }
25922
- '409': { description: 'Sender ID already registered by another workspace (code `sender_id_taken`).' }
25923
- '422': { description: 'Sender ID rejected: it appears to impersonate a protected brand or institution.' }
25924
- get:
25925
- operationId: listSmsSenderIds
25926
- tags: [SMS]
25927
- summary: List alphanumeric sender IDs
25928
- security:
25929
- - bearerAuth: []
25930
- responses:
25931
- '200':
25932
- description: The workspace's sender IDs, newest first.
25933
- content:
25934
- application/json:
25935
- schema:
25936
- type: object
25937
- properties:
25938
- senderIds:
25939
- type: array
25940
- items:
25941
- type: object
25942
- properties:
25943
- id: { type: string }
25944
- senderId: { type: string }
25945
- isActive: { type: boolean }
25946
- createdAt: { type: [string, "null"], format: date-time }
25947
- budget:
25948
- type: object
25949
- description: 'Workspace-wide daily sending budget, shared by every sender ID (resets midnight UTC).'
25950
- properties:
25951
- cap: { type: integer, description: 'Daily message cap (raisable via `/v1/sms/sender-ids/limit-request`).' }
25952
- usedToday: { type: integer, description: Messages already counted against today's cap. }
25953
- level: { type: integer, description: 'Cap tier (Level 1 = 500/day).' }
25954
- pendingRequest:
25955
- type: [object, "null"]
25956
- description: 'The in-flight cap-raise request awaiting review, or null. While set, further requests return 409.'
25957
- properties:
25958
- requestedCap: { type: integer }
25959
- level: { type: integer }
25960
- requestedAt: { type: [string, "null"], format: date-time }
25961
- '401': { $ref: '#/components/responses/Unauthorized' }
25962
-
25963
- /v1/sms/sender-ids/limit-request:
25964
- post:
25965
- operationId: requestSmsSenderIdLimitIncrease
25966
- tags: [SMS]
25967
- summary: Request a higher sender ID daily limit
25968
- description: |
25969
- Asks support to raise the workspace's daily sender-ID message cap.
25970
- There is no self-serve raise: the request (desired cap + use case) is
25971
- reviewed manually, usually within a business day.
25972
- security:
25973
- - bearerAuth: []
25974
- requestBody:
25975
- required: true
25976
- content:
25977
- application/json:
25978
- schema:
25979
- type: object
25980
- required: [requestedCap, reason]
25981
- properties:
25982
- requestedCap: { type: integer, description: 'Desired daily message cap. Must exceed the current cap.' }
25983
- reason: { type: string, minLength: 10, maxLength: 2000, description: 'Use case and audience (what you send, to whom, opt-in status).' }
25984
- responses:
25985
- '200':
25986
- description: Request submitted for review.
25987
- content:
25988
- application/json:
25989
- schema:
25990
- type: object
25991
- properties:
25992
- requested: { type: boolean }
25993
- requestedCap: { type: integer }
25994
- '400': { $ref: '#/components/responses/BadRequest' }
25995
- '401': { $ref: '#/components/responses/Unauthorized' }
25996
- '409': { description: 'A cap-raise request is already awaiting review (code `sender_id_raise_pending`); one at a time.' }
25997
- '503': { description: Request could not be submitted; retry or contact support. }
25998
-
25999
- /v1/sms/sender-ids/{id}:
26000
- delete:
26001
- operationId: deleteSmsSenderId
26002
- tags: [SMS]
26003
- summary: Delete an alphanumeric sender ID
26004
- description: |
26005
- Deactivates the sender ID so it can no longer send. Re-creating the
26006
- same sender ID via `POST /v1/sms/sender-ids` re-activates it.
26007
- security:
26008
- - bearerAuth: []
26009
- parameters:
26010
- - { name: id, in: path, required: true, schema: { type: string }, description: Sender ID resource id. }
26011
- responses:
26012
- '200':
26013
- description: Sender ID deactivated.
26014
- content:
26015
- application/json:
26016
- schema:
26017
- type: object
26018
- properties:
26019
- deleted: { type: boolean }
26020
- '400': { $ref: '#/components/responses/BadRequest' }
26021
- '401': { $ref: '#/components/responses/Unauthorized' }
26022
- '404': { description: Sender ID not found. }
26023
-
26024
25925
  /v1/sms/registrations:
26025
25926
  post:
26026
25927
  operationId: startSmsRegistration
@@ -33109,54 +33010,6 @@ paths:
33109
33010
  '401': { $ref: '#/components/responses/Unauthorized' }
33110
33011
  '403':
33111
33012
  description: Ads access required. Legacy plans need the Ads add-on; included by default on usage-based plans.
33112
- post:
33113
- operationId: createAdCampaign
33114
- tags: [Ad Campaigns]
33115
- summary: Create a standalone campaign (Meta)
33116
- description: |-
33117
- Creates a campaign WITHOUT its first ad set / ad (the ODAX shell only). Ad sets join it
33118
- later via `existingCampaignId` on the create endpoints. A budget here is campaign-level
33119
- (CBO) by definition; omit it for ABO (each ad set carries its own budget). Created
33120
- `PAUSED` unless `status: ACTIVE`. The campaign materializes in `/v1/ads/tree` via the
33121
- next sync discovery pass. Meta only.
33122
- security:
33123
- - bearerAuth: []
33124
- requestBody:
33125
- required: true
33126
- content:
33127
- application/json:
33128
- schema:
33129
- type: object
33130
- required: [accountId, adAccountId, name, goal]
33131
- properties:
33132
- accountId: { type: string, description: "Zernio SocialAccount id (posting or ads variant) used to resolve the Meta token." }
33133
- adAccountId: { type: string, description: "Meta ad account id (act_<n>)." }
33134
- name: { type: string, maxLength: 255 }
33135
- goal:
33136
- type: string
33137
- enum: [engagement, traffic, awareness, video_views, lead_generation, lead_conversion, job_applicants, conversions, app_promotion, catalog_sales]
33138
- description: Mapped to the ODAX objective (same mapping as POST /v1/ads/create).
33139
- specialAdCategories:
33140
- type: array
33141
- items: { type: string, enum: [HOUSING, EMPLOYMENT, CREDIT, ISSUES_ELECTIONS_POLITICS, FINANCIAL_PRODUCTS_SERVICES, ONLINE_GAMBLING_AND_GAMING] }
33142
- budgetAmount: { type: number, description: "Campaign-level (CBO) budget in whole currency units. Requires budgetType." }
33143
- budgetType: { type: string, enum: [daily, lifetime] }
33144
- status: { type: string, enum: [ACTIVE, PAUSED], default: PAUSED }
33145
- responses:
33146
- '201':
33147
- description: Campaign created
33148
- content:
33149
- application/json:
33150
- schema:
33151
- type: object
33152
- properties:
33153
- adAccountId: { type: string }
33154
- campaignId: { type: string, description: Platform id of the new campaign }
33155
- objective: { type: string, description: "Resolved ODAX objective (e.g. OUTCOME_SALES)." }
33156
- status: { type: string, enum: [ACTIVE, PAUSED] }
33157
- '400': { description: "Invalid input, or Meta rejected the create" }
33158
- '401': { $ref: '#/components/responses/Unauthorized' }
33159
- '501': { description: Only supported on Meta (facebook/instagram) }
33160
33013
 
33161
33014
  /v1/ads/campaigns/{campaignId}/status:
33162
33015
  put:
@@ -33445,98 +33298,6 @@ paths:
33445
33298
  '404': { description: Source campaign not found }
33446
33299
  '501': { description: Operation not supported on this platform }
33447
33300
 
33448
- /v1/ads/ad-sets/{adSetId}/duplicate:
33449
- post:
33450
- operationId: duplicateAdSet
33451
- tags: [Ad Campaigns]
33452
- summary: Duplicate an ad set (Meta)
33453
- description: |-
33454
- Duplicates an ad set, including its ads and creatives by default (`deepCopy: true`),
33455
- via Meta's native `POST /{adset-id}/copies`. The copy is created paused so callers can
33456
- review before launching. `campaignId` retargets the copy into another campaign; omitted
33457
- = the source's own campaign. The new hierarchy materializes asynchronously — sync
33458
- discovery is triggered automatically (`syncAfter: false` to skip). Meta only.
33459
- security:
33460
- - bearerAuth: []
33461
- parameters:
33462
- - { name: adSetId, in: path, required: true, schema: { type: string }, description: Source platform ad set ID }
33463
- requestBody:
33464
- required: true
33465
- content:
33466
- application/json:
33467
- schema:
33468
- type: object
33469
- required: [platform]
33470
- properties:
33471
- platform: { type: string, enum: [facebook, instagram] }
33472
- campaignId: { type: string, description: Destination platform campaign id (defaults to the source's campaign) }
33473
- deepCopy: { type: boolean, default: true, description: Copy child ads + creatives }
33474
- statusOption: { type: string, enum: [ACTIVE, PAUSED, INHERITED_FROM_SOURCE], default: PAUSED }
33475
- startTime: { type: string, format: date-time, description: Reschedule the copy's start time }
33476
- endTime: { type: string, format: date-time }
33477
- renameStrategy: { type: string, enum: [DEEP_RENAME, ONLY_TOP_LEVEL_RENAME, NO_RENAME] }
33478
- renamePrefix: { type: string }
33479
- renameSuffix: { type: string }
33480
- syncAfter: { type: boolean, default: true }
33481
- responses:
33482
- '200':
33483
- description: Ad set duplicated
33484
- content:
33485
- application/json:
33486
- schema:
33487
- type: object
33488
- properties:
33489
- copiedAdSetId: { type: string, description: Platform ID of the new ad set }
33490
- discovery: { type: string, enum: [triggered, skipped, failed] }
33491
- raw: { type: object, description: Meta's native copy response (includes ad_object_ids for child copies) }
33492
- '400': { description: Invalid input }
33493
- '401': { $ref: '#/components/responses/Unauthorized' }
33494
- '404': { description: Source ad set not found }
33495
- '501': { description: Only supported on Meta (facebook/instagram) }
33496
-
33497
- /v1/ads/{adId}/duplicate:
33498
- post:
33499
- operationId: duplicateAd
33500
- tags: [Ads]
33501
- summary: Duplicate an ad (Meta)
33502
- description: |-
33503
- Duplicates a single ad via Meta's native `POST /{ad-id}/copies`. The copy is created
33504
- paused. `adSetId` retargets the copy into another ad set; omitted = the source's own ad
33505
- set. Accepts the Zernio ad id or the platform ad id. Sync discovery is triggered
33506
- automatically (`syncAfter: false` to skip). Meta only.
33507
- security:
33508
- - bearerAuth: []
33509
- parameters:
33510
- - { name: adId, in: path, required: true, schema: { type: string }, description: Zernio ad ID or platform ad ID }
33511
- requestBody:
33512
- required: false
33513
- content:
33514
- application/json:
33515
- schema:
33516
- type: object
33517
- properties:
33518
- adSetId: { type: string, description: Destination platform ad set id (defaults to the source's ad set) }
33519
- statusOption: { type: string, enum: [ACTIVE, PAUSED, INHERITED_FROM_SOURCE], default: PAUSED }
33520
- renameStrategy: { type: string, enum: [DEEP_RENAME, ONLY_TOP_LEVEL_RENAME, NO_RENAME] }
33521
- renamePrefix: { type: string }
33522
- renameSuffix: { type: string }
33523
- syncAfter: { type: boolean, default: true }
33524
- responses:
33525
- '200':
33526
- description: Ad duplicated
33527
- content:
33528
- application/json:
33529
- schema:
33530
- type: object
33531
- properties:
33532
- copiedAdId: { type: string, description: Platform ID of the new ad }
33533
- discovery: { type: string, enum: [triggered, skipped, failed] }
33534
- raw: { type: object }
33535
- '400': { description: Invalid input }
33536
- '401': { $ref: '#/components/responses/Unauthorized' }
33537
- '404': { description: Ad not found }
33538
- '501': { description: Only supported on Meta (facebook/instagram) }
33539
-
33540
33301
  /v1/ads/ad-sets/{adSetId}:
33541
33302
  get:
33542
33303
  operationId: getAdSetDetails
@@ -34859,263 +34620,6 @@ paths:
34859
34620
  '401': { $ref: '#/components/responses/Unauthorized' }
34860
34621
  '501': { description: Only supported on Meta (facebook/instagram) }
34861
34622
 
34862
- /v1/ads/labels:
34863
- get:
34864
- operationId: listAdLabels
34865
- tags: [Ads]
34866
- summary: Ad labels (Meta)
34867
- description: |-
34868
- Lists the ad account's organizational labels (Meta's `/act_X/adlabels`), rows returned
34869
- verbatim (id, name, created/updated time). Meta only.
34870
- security:
34871
- - bearerAuth: []
34872
- parameters:
34873
- - { name: accountId, in: query, required: true, schema: { type: string }, description: "Zernio SocialAccount id (posting or ads variant) used to resolve the Meta token." }
34874
- - { name: adAccountId, in: query, required: true, schema: { type: string }, description: "Meta ad account id (act_<n>)." }
34875
- - { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 25 }, description: Rows per page }
34876
- - { name: after, in: query, schema: { type: string }, description: "Cursor from paging.after of the previous page." }
34877
- responses:
34878
- '200':
34879
- description: Ad labels (raw Meta shape)
34880
- content:
34881
- application/json:
34882
- schema:
34883
- type: object
34884
- properties:
34885
- adAccountId: { type: string }
34886
- data:
34887
- type: array
34888
- items: { type: object, description: "Raw Meta ad label row (id, name, created_time, updated_time)." }
34889
- paging:
34890
- type: object
34891
- properties:
34892
- after: { type: [string, "null"], description: "Cursor for the next page; null when exhausted." }
34893
- '400': { description: "Invalid input, or Meta rejected the query" }
34894
- '401': { $ref: '#/components/responses/Unauthorized' }
34895
- '501': { description: Only supported on Meta (facebook/instagram) }
34896
-
34897
- /v1/ads/high-demand-periods:
34898
- get:
34899
- operationId: listHighDemandPeriods
34900
- tags: [Ads]
34901
- summary: High demand periods / budget schedules (Meta)
34902
- description: |-
34903
- Scheduled budget increases (Meta's budget-scheduling API). The Graph edge lives on the
34904
- campaign and ad-set nodes only, so exactly one of `campaignId` / `adSetId` (platform
34905
- ids) is required. Rows returned verbatim (budget_value, budget_value_type, time window,
34906
- recurrence). Meta only.
34907
- security:
34908
- - bearerAuth: []
34909
- parameters:
34910
- - { name: accountId, in: query, required: true, schema: { type: string }, description: "Zernio SocialAccount id (posting or ads variant) used to resolve the Meta token." }
34911
- - { name: campaignId, in: query, schema: { type: string }, description: "Platform campaign id. Exactly one of campaignId / adSetId." }
34912
- - { name: adSetId, in: query, schema: { type: string }, description: "Platform ad set id. Exactly one of campaignId / adSetId." }
34913
- - { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 25 }, description: Rows per page }
34914
- - { name: after, in: query, schema: { type: string }, description: "Cursor from paging.after of the previous page." }
34915
- responses:
34916
- '200':
34917
- description: Budget schedules (raw Meta shape)
34918
- content:
34919
- application/json:
34920
- schema:
34921
- type: object
34922
- properties:
34923
- objectId: { type: string, description: "The campaign / ad set id the schedules belong to." }
34924
- data:
34925
- type: array
34926
- items: { type: object, description: "Raw Meta high-demand-period row." }
34927
- paging:
34928
- type: object
34929
- properties:
34930
- after: { type: [string, "null"], description: "Cursor for the next page; null when exhausted." }
34931
- '400': { description: "Invalid input, or Meta rejected the query" }
34932
- '401': { $ref: '#/components/responses/Unauthorized' }
34933
- '501': { description: Only supported on Meta (facebook/instagram) }
34934
-
34935
- /v1/ads/creatives:
34936
- get:
34937
- operationId: listAdCreatives
34938
- tags: [Ads]
34939
- summary: Creative library (Meta)
34940
- description: |-
34941
- Lists the ad account's creative library (Meta's `/act_X/adcreatives`), rows returned
34942
- verbatim. The default projection covers id, name, status, object type, thumbnail,
34943
- object_story_spec / asset_feed_spec and url_tags; `fields` is a raw-passthrough
34944
- override. Any creative id here is reusable on the create endpoints via
34945
- `existingCreativeId`. Meta only.
34946
- security:
34947
- - bearerAuth: []
34948
- parameters:
34949
- - { name: accountId, in: query, required: true, schema: { type: string }, description: "Zernio SocialAccount id (posting or ads variant) used to resolve the Meta token." }
34950
- - { name: adAccountId, in: query, required: true, schema: { type: string }, description: "Meta ad account id (act_<n>)." }
34951
- - { name: fields, in: query, schema: { type: string }, description: "Comma-separated Graph field override (supports nested {} projections)." }
34952
- - { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 25 }, description: Rows per page }
34953
- - { name: after, in: query, schema: { type: string }, description: "Cursor from paging.after of the previous page." }
34954
- responses:
34955
- '200':
34956
- description: Creatives (raw Meta shape)
34957
- content:
34958
- application/json:
34959
- schema:
34960
- type: object
34961
- properties:
34962
- adAccountId: { type: string }
34963
- data:
34964
- type: array
34965
- items: { type: object, description: "Raw Meta creative row." }
34966
- paging:
34967
- type: object
34968
- properties:
34969
- after: { type: [string, "null"], description: "Cursor for the next page; null when exhausted." }
34970
- '400': { description: "Invalid input, or Meta rejected the query" }
34971
- '401': { $ref: '#/components/responses/Unauthorized' }
34972
- '501': { description: Only supported on Meta (facebook/instagram) }
34973
- post:
34974
- operationId: createAdCreative
34975
- tags: [Ads]
34976
- summary: Create a standalone creative (Meta)
34977
- description: |-
34978
- Creates a creative in the library WITHOUT an ad, reusable on the create endpoints via
34979
- `existingCreativeId`. Provide exactly one of `imageUrl` (uploaded server-side),
34980
- `imageHash` (from POST /v1/ads/images or the library list), or `carouselCards` (2-10
34981
- hand-built cards). The Page (and linked Instagram account, when present) is resolved
34982
- from `accountId` as the story actor. Meta only.
34983
- security:
34984
- - bearerAuth: []
34985
- requestBody:
34986
- required: true
34987
- content:
34988
- application/json:
34989
- schema:
34990
- type: object
34991
- required: [accountId, adAccountId, headline, body, linkUrl]
34992
- properties:
34993
- accountId: { type: string, description: "Zernio SocialAccount id (posting or ads variant) used to resolve the Meta token and Page." }
34994
- adAccountId: { type: string, description: "Meta ad account id (act_<n>)." }
34995
- headline: { type: string, maxLength: 255 }
34996
- body: { type: string, description: Primary text }
34997
- description: { type: string, maxLength: 255, description: "Link description below the headline; omitted = Meta scrapes the destination's OG description." }
34998
- callToAction: { type: string, default: LEARN_MORE, description: "CTA type (same whitelist as POST /v1/ads/create)." }
34999
- linkUrl: { type: string, format: uri }
35000
- imageUrl: { type: string, format: uri, description: "Publicly reachable image; uploaded to the account's library server-side." }
35001
- imageHash: { type: string, description: "Existing library image hash (POST /v1/ads/images or GET /v1/ads/images)." }
35002
- carouselCards:
35003
- type: array
35004
- minItems: 2
35005
- maxItems: 10
35006
- items:
35007
- type: object
35008
- required: [imageUrl, linkUrl]
35009
- properties:
35010
- imageUrl: { type: string, format: uri }
35011
- linkUrl: { type: string, format: uri }
35012
- headline: { type: string, maxLength: 255 }
35013
- description: { type: string, maxLength: 255 }
35014
- callToAction: { type: string }
35015
- urlTags: { type: string, description: "Appended to every outbound URL (e.g. utm_source=fb)." }
35016
- responses:
35017
- '201':
35018
- description: Creative created
35019
- content:
35020
- application/json:
35021
- schema:
35022
- type: object
35023
- properties:
35024
- adAccountId: { type: string }
35025
- creativeId: { type: string, description: "Platform creative id, reusable via existingCreativeId." }
35026
- '400': { description: "Invalid input, or Meta rejected the create" }
35027
- '401': { $ref: '#/components/responses/Unauthorized' }
35028
- '422': { description: No Facebook Page found to act as the story actor }
35029
- '501': { description: Only supported on Meta (facebook/instagram) }
35030
-
35031
- /v1/ads/creatives/{creativeId}:
35032
- get:
35033
- operationId: getAdCreative
35034
- tags: [Ads]
35035
- summary: Creative details (Meta)
35036
- description: |-
35037
- One creative's details, verbatim from Meta. `fields` is a raw-passthrough override of
35038
- the default projection. Meta only.
35039
- security:
35040
- - bearerAuth: []
35041
- parameters:
35042
- - { name: creativeId, in: path, required: true, schema: { type: string }, description: Platform creative id }
35043
- - { name: accountId, in: query, required: true, schema: { type: string }, description: "Zernio SocialAccount id (posting or ads variant) used to resolve the Meta token." }
35044
- - { name: fields, in: query, schema: { type: string }, description: "Comma-separated Graph field override (supports nested {} projections)." }
35045
- responses:
35046
- '200':
35047
- description: Creative details
35048
- content:
35049
- application/json:
35050
- schema:
35051
- type: object
35052
- properties:
35053
- creative: { type: object, description: Raw Meta creative node }
35054
- '400': { description: "Invalid input, or Meta rejected the query" }
35055
- '401': { $ref: '#/components/responses/Unauthorized' }
35056
- '501': { description: Only supported on Meta (facebook/instagram) }
35057
- put:
35058
- operationId: updateAdCreative
35059
- tags: [Ads]
35060
- summary: Rename a creative (Meta)
35061
- description: |-
35062
- Renames a creative. Creatives are immutable on Meta beyond `name` — for content changes
35063
- create a new creative (POST /v1/ads/creatives) and swap it onto the ad
35064
- (PUT /v1/ads/{adId} with `creative`). Meta only.
35065
- security:
35066
- - bearerAuth: []
35067
- parameters:
35068
- - { name: creativeId, in: path, required: true, schema: { type: string }, description: Platform creative id }
35069
- requestBody:
35070
- required: true
35071
- content:
35072
- application/json:
35073
- schema:
35074
- type: object
35075
- required: [accountId, name]
35076
- properties:
35077
- accountId: { type: string, description: "Zernio SocialAccount id (posting or ads variant) used to resolve the Meta token." }
35078
- name: { type: string, maxLength: 255 }
35079
- responses:
35080
- '200':
35081
- description: Creative renamed
35082
- content:
35083
- application/json:
35084
- schema:
35085
- type: object
35086
- properties:
35087
- creativeId: { type: string }
35088
- name: { type: string }
35089
- message: { type: string }
35090
- '400': { description: "Invalid input, or Meta rejected the update" }
35091
- '401': { $ref: '#/components/responses/Unauthorized' }
35092
- '501': { description: Only supported on Meta (facebook/instagram) }
35093
- delete:
35094
- operationId: deleteAdCreative
35095
- tags: [Ads]
35096
- summary: Delete a creative (Meta)
35097
- description: |-
35098
- Deletes a creative from the library. Meta only allows deleting creatives not referenced
35099
- by any ad — otherwise its 400 surfaces verbatim.
35100
- security:
35101
- - bearerAuth: []
35102
- parameters:
35103
- - { name: creativeId, in: path, required: true, schema: { type: string }, description: Platform creative id }
35104
- - { name: accountId, in: query, required: true, schema: { type: string }, description: "Zernio SocialAccount id (posting or ads variant) used to resolve the Meta token." }
35105
- responses:
35106
- '200':
35107
- description: Creative deleted
35108
- content:
35109
- application/json:
35110
- schema:
35111
- type: object
35112
- properties:
35113
- creativeId: { type: string }
35114
- message: { type: string }
35115
- '400': { description: "Invalid input, the creative is in use, or Meta rejected the delete" }
35116
- '401': { $ref: '#/components/responses/Unauthorized' }
35117
- '501': { description: Only supported on Meta (facebook/instagram) }
35118
-
35119
34623
  /v1/ads/accounts/finance:
35120
34624
  get:
35121
34625
  operationId: getAdAccountFinance
@@ -36562,42 +36066,6 @@ paths:
36562
36066
  '400': { description: "Invalid input, or Meta rejected the image" }
36563
36067
  '401': { $ref: '#/components/responses/Unauthorized' }
36564
36068
  '501': { description: Only supported on Meta (facebook/instagram) }
36565
- get:
36566
- operationId: listAdImages
36567
- tags: [Ads]
36568
- summary: Ad image library (Meta)
36569
- description: |-
36570
- Lists the ad account's image library (Meta's `/act_X/adimages`), rows returned verbatim.
36571
- The default projection covers hash, url, name, dimensions and status; `fields` is a
36572
- raw-passthrough override. Any `hash` here is reusable wherever Meta accepts
36573
- `image_hash` (e.g. `imageHash` on POST /v1/ads/creatives). Meta only.
36574
- security:
36575
- - bearerAuth: []
36576
- parameters:
36577
- - { name: accountId, in: query, required: true, schema: { type: string }, description: "Zernio SocialAccount id (posting or ads variant) used to resolve the Meta token." }
36578
- - { name: adAccountId, in: query, required: true, schema: { type: string }, description: "Meta ad account id (act_<n>)." }
36579
- - { name: fields, in: query, schema: { type: string }, description: "Comma-separated Graph field override (supports nested {} projections)." }
36580
- - { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 25 }, description: Rows per page }
36581
- - { name: after, in: query, schema: { type: string }, description: "Cursor from paging.after of the previous page." }
36582
- responses:
36583
- '200':
36584
- description: Ad images (raw Meta shape)
36585
- content:
36586
- application/json:
36587
- schema:
36588
- type: object
36589
- properties:
36590
- adAccountId: { type: string }
36591
- data:
36592
- type: array
36593
- items: { type: object, description: "Raw Meta ad image row (hash, url, name, width, height, status)." }
36594
- paging:
36595
- type: object
36596
- properties:
36597
- after: { type: [string, "null"], description: "Cursor for the next page; null when exhausted." }
36598
- '400': { description: "Invalid input, or Meta rejected the query" }
36599
- '401': { $ref: '#/components/responses/Unauthorized' }
36600
- '501': { description: Only supported on Meta (facebook/instagram) }
36601
36069
 
36602
36070
  /v1/ads/interests:
36603
36071
  get:
@@ -37169,15 +36637,12 @@ paths:
37169
36637
  put:
37170
36638
  operationId: updateAdAudience
37171
36639
  tags: [Ad Audiences]
37172
- summary: Update an audience
36640
+ summary: Update saved targeting audience
37173
36641
  description: |
37174
- Update an audience. `saved_targeting` audiences accept `name`, `description`, and `spec`
37175
- (full replacement, no merge, Zernio-only, no platform call). Platform audiences
37176
- (uploaded/website/lookalike) accept `name` and `description` only, updated on the
37177
- platform first and then mirrored locally; their rules are immutable, so `spec` returns
37178
- 400 for them. Platform audience updates are Meta-only for now (other platforms return
37179
- 501). Ads already created from a saved_targeting audience are unaffected, they snapshot
37180
- the targeting at creation.
36642
+ Update a `saved_targeting` audience's name, description, or spec. Only `saved_targeting` audiences are
36643
+ updatable (they exist only on Zernio); uploaded/derived audiences return 422, delete and recreate those
36644
+ instead. `spec` replaces the stored spec wholesale (no merge). Ads already created from this audience are
36645
+ unaffected, they snapshot the targeting at creation.
37181
36646
  security:
37182
36647
  - bearerAuth: []
37183
36648
  parameters:
@@ -37206,15 +36671,13 @@ paths:
37206
36671
  audience: { type: object }
37207
36672
  message: { type: string }
37208
36673
  '400':
37209
- description: 'Invalid body (no fields provided, malformed spec, or spec on a platform audience)'
36674
+ description: Invalid body (no fields provided or malformed spec)
37210
36675
  '401': { $ref: '#/components/responses/Unauthorized' }
37211
36676
  '403':
37212
36677
  description: Ads access required. Legacy plans need the Ads add-on; included by default on usage-based plans.
37213
36678
  '404': { $ref: '#/components/responses/NotFound' }
37214
36679
  '422':
37215
- description: The audience has no platform counterpart to update
37216
- '501':
37217
- description: Platform audience updates are only supported on Meta
36680
+ description: The audience is not saved_targeting (uploaded/derived audiences are managed on the platform)
37218
36681
  delete:
37219
36682
  operationId: deleteAdAudience
37220
36683
  tags: [Ad Audiences]