Automations API
https://zap-api.omnivery.net
The Omnivery Automations API is a lightweight API intended for easy 3rd party integrations mostly with low-code and no-code platforms like Make.com or Zapier.
Purpose of this API is to simplify development of integrations as much as possible.
Authentication
-
API Key:
API Key in header as
ov-token
Enter your credentials below to use the Try it feature:
Bot Detection
Use of this endpoint is limited to domains that have access to Bot Detection API. Contact our sales to inquire about using our botDetection product.
Validate Batch of Interactions
This is the primary mode of use for the API that allows you to post as a JSON object with interactions for detection in bulk. The submission size is limited to 500 events in a single request.
Each interaction in the events array must contain at least ip, uas and event_id. We highly recommend you to provide as much available information about each interaction as possible as it greatly increases detection accuracy. You are welcome to pass your own attributes within the event object you may find usefull to be passed back to you in the webhook call.
Required elements of the event object:
| Parameter | Description |
|---|---|
| ip | Interaction source IP - provide the IP of the origin performing the request |
| uas | Interaction User Agent string of the client that performed the original request |
| event_id | Unique identifier of the event - this is the identifier you will be able to use to identify the detection result and will be returned in the webhook call |
| action | Interaction action (open/click) - defaults to click if not set |
| domain | Recipient's email address domain part - this is not to be hashed as the domain part is used to look up MX servers of the domain |
| recipient_id | Recipient identifier - an identifier of a unique recipient. This could be a hash of an email address's local part, email ID or even the email's localpart itself. For privacy resons we recommend using hashes in the recipient_id. |
| message_id | Unique message identifier - the identifier is used to distinguish between interactions of the same recipient across multiple messages. This could be the original message-id, internal ID or a hash representing any unique message identifier |
| ts | Interaction Timestamp (unixtime) |
| message_ts | Timestamp of message delivery if available (unixtime) |
Validate Single Interaction
This method allows you to validate a single interaction posted as form-data to identify if the interaction has been performed by a human or a bot. It's important to note that while the detection only requires either ip or uas to be provided in the request, the additional information provided will increase accuracy.
NOTE: For security reasons this endpoint has HIGH latency and will no return results earlier than in 1 second. The endpoint is also protected by additional security measures such as rate limits to prevent any abuse. This endpoint is NOT intended for synchronous use.
The server can either respond with a result synchronously with status code 200 or return a response with a status code 202 and provide a request_id of your request. In such case you will have to query the Retrieve Result endpoint or wait for the result to be pushed to the webhook endpoint if provided.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain |
path | string | Yes | Domain to use for Bot Detection validations |
Request Body application/json
| Field | Type | Required | Description | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
events |
array | Yes | |||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
webhook_url |
string | Yes | Webhook endpoint URL to push results to |
||||||||||||||||||||||||||||||||||||||||
Responses
Bad Request
Unauthorized
{
"message": "Unauthorized"
}
Payment Required
{
"message": "BotDetection API not enabled for this domain. Contact sales@omnivery.com.",
"status": 402
}
OK
Accepted
Code Samples
curl -X POST 'https://zap-api.omnivery.net/{domain}/bot' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY' \
-d '{"events": [], "webhook_url": "string"}'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://zap-api.omnivery.net/{domain}/bot", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/{domain}/bot', {
method: 'POST',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
body: JSON.stringify({"events": [], "webhook_url": "string"})
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/{domain}/bot');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"events": [], "webhook_url": "string"}');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.post(
'https://zap-api.omnivery.net/{domain}/bot',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
json={"events": [], "webhook_url": "string"}
)
print(response.json())
Response
Retrieve validatoin result
This endpoint allows you to retrieve a single validation result using the request_id provided in the response to the Validate single interaction request.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain |
path | string | Yes | Domain used for validation |
request_id |
path | string | Yes | Original request_id as returned in the validation response |
Responses
Not Found
{
"message": "Request with matching UUID not found. It may not have been processed yet or has already expired.",
"status": 404
}
OK
{
"is_bot": false,
"request": {
"action": "click",
"domain": "dolnyslask.pl",
"event_id": "57d476d4-d8db-4757-b4da-5f2b8d6bf5f5",
"ip": "156.17.201.170",
"message_id": "17690841631",
"recipient_id": "randomhash",
"ts": 1721474736,
"uas": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1",
"webhook_url": "https://webhook.site/ab780a76-e094-46f5-805f-0de96c99d2e5"
}
}
Code Samples
curl -X GET 'https://zap-api.omnivery.net/{domain}/bot/{request_id}' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://zap-api.omnivery.net/{domain}/bot/{request_id}", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/{domain}/bot/{request_id}', {
method: 'GET',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/{domain}/bot/{request_id}');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.get(
'https://zap-api.omnivery.net/{domain}/bot/{request_id}',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
)
print(response.json())
Response
Bot Detection Honeypots
Omnivery Bot Detection API provides a honeypot feature for faster and more accurate identification of infrastructures that sit outside of current datasets. Use of the honeypots allows our engine to collect data and create a detection "shortcut" to provide increased detection accuracy for on-premise security solutions as well as malicious botnets where frequency detection may not capture all events.
The honeypot is implemented by adding a hidden link to the message body, preferably at the end of the body. The most common implementation would be to wrap it around the tracking pixel or make it an empty link:
<a href="https://email.{domain}/{message_id}/hclick">...tracking pixel code...</a> or
<a href=”https://email.{domain}/{message_id}/hclick”></a>
In case your platform is already adding honeypot links for your internal purposes, it is not advisable to have your existing honeypot link redirect to our honeypot address.
It is crucial that the message_id used in the link matches the message_id posted in the event for Bot Detection. Please note that the "message_id" attribute can be any unique message identifier in your platform and doesn't necessarily have to match the message-id header of the actual email message sent.
The honeypots record only the IP address and User-Agent string of the visitor in a temporary cache for 30 minutes. It's important that event data are submitted to our API within 30 minutes to take advantage of detection using honeypot hits.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain |
path | string | Yes | Domain used for honeypot |
message_id |
path | string | Yes | Unique message identifier - this MUST match the identifier passed as message_id to the validation endpoint |
Code Samples
curl -X GET 'https://zap-api.omnivery.net{domain}/{message_id}/hclick' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://zap-api.omnivery.net{domain}/{message_id}/hclick", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net{domain}/{message_id}/hclick', {
method: 'GET',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net{domain}/{message_id}/hclick');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.get(
'https://zap-api.omnivery.net{domain}/{message_id}/hclick',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
)
print(response.json())
Response
Webhook data
Each event result processed by the botDetection API will be pushed to a webhook provided in the API call. The JSON array events will contain the same objects as posted in the request with each individual event extended with detection result is_bot.
An additional object signature allows you to validate the authenticity of the result by calculating verifying the signature.
Request Body application/json
| Field | Type | Required | Description | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
signature |
object | No | The signature object allows you to verify the authenticity of the webhook call |
||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
batch |
object | No | Object containing information about the batch |
||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
events |
object | No | An object containing data about interactions |
||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
Responses
Code Samples
curl -X POST 'https://zap-api.omnivery.net/webhook' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY' \
-d '{"signature": {}, "batch": {}, "events": {}}'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://zap-api.omnivery.net/webhook", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/webhook', {
method: 'POST',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
body: JSON.stringify({"signature": {}, "batch": {}, "events": {}})
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/webhook');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"signature": {}, "batch": {}, "events": {}}');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.post(
'https://zap-api.omnivery.net/webhook',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
json={"signature": {}, "batch": {}, "events": {}}
)
print(response.json())
Response
Sends a message from a domain specified in the URL by assembling it from the components. Note that you can specify most parameters multiple times, HTTP supports this out of the box. This makes sense for parameters like cc, to or attachment.
NOTE: This API endpoint can be used using both primary and sending API keys. It's strongly recommended to only use sending API keys for sending messages for security reasons.
| Parameter | Description |
|---|---|
| domain | Domain to be used for sending the message. Domain must be verified and active. This parameter is part of the URL |
| from | Email address for From header. Example: "Sender Name" sender@example.org. |
| to | Email address of the recipient(s). Example: "John Doe" johndoe@example.org. You can use commas to separate multiple recipients. |
| reply_to | Email address for the Reply-to header. Example: "John Doe" johndoe@example.org. |
| cc | Same as To but for Cc |
| bcc | Same as To but for Bcc |
| subject | Message subject |
| text | Body of the message. (text version) |
| html | Body of the message. (HTML version) |
| attachment | File attachment. You can post multiple attachment values. Important: You must use multipart/form-data encoding when sending attachments. |
| inline | Attachment with inline disposition. Can be used to send inline images (see example). You can post multiple inline values. |
| o:tag | Tag string. |
| o:testmode | Enables sending in test mode. Pass yes if needed. |
| o:tracking | Toggles tracking on a per-message basis. Pass yes or no. |
| h:X-My-Header | h: prefix followed by an arbitrary value allows to append a custom MIME header to the message (X-My-Header in this case). For example, h:Reply-To to specify Reply-To address. |
| v:my-var | v: prefix followed by an arbitrary name allows to attach a custom JSON data to the message. |
| callback_url | Sets a webhook endpoint URL to post events to. Setting callback_url in the call gives you more granular control over the webhook endpoints than having the webhooks set on domain level. |
| template | Use a stored template to generate the message content |
| template_variables | Pass structured variables to the template for processing |
Message security
Errors and attacks are not uncommon and we do our best to protect your account. Check out how we deduplicate messages and how you can further secure your domain.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain |
path | string | Yes | Domain to be used for sending the message |
Request Body multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
reply_to |
string | No | Email addres for |
to |
string | No | Email address of the recipient(s). Example: |
inline |
string | No | Attachment with inline disposition. Can be used to send inline images (see example). You can post multiple inline values. |
bcc |
string | No | Same as |
callback_url |
string | No | Sets a webhook endpoint URL to post events to. Setting callback_url in the call gives you more granular control over the webhook endpoints than having the webhooks set on domain level. |
domain |
string | No | Domain to be used for sending the message. Domain must be verified and active. |
h:X-Mailgun-Variables |
string | No | h: prefix followed by an arbitrary value allows to append a custom MIME header to the message (X-My-testid in this case). For example, h:Reply-To to specify Reply-To address. |
o:tracking-opens |
string | No | Toggles message open tracking on a per-message basis |
h:Test |
string | No | Adds a header to your message with name "Test" and value "randomtexthere" |
o:testmode |
boolean | No | Enables sending in test mode |
template |
string | No | Use a template of a given filename stored in the Omnivery UI to generate the message body. |
template_variables |
string | No | Pass a JSON encoded structure with variables for templatate to process. Unlike recipient variables passed using |
v:chars |
string | No | |
v:fname |
string | No | v: prefix followed by an arbitrary name allows to attach custom data to the message. It's recommended the content for custom data is JSON encoded. |
v:link.url |
string | No | Variable to be passed to the message. Variables can be used within templates or for message identification as they are stored in message headers. |
o:tracking |
string | No | Toggles tracking on a per-message basis |
amp-html |
string | No | AMP part of the message |
attachment |
string | No | File attachment. You can post multiple attachment values. Important: You must use multipart/form-data encoding when sending attachments. |
cc |
string | No | Same as |
from |
string | No | Email address for |
o:tracking-clicks |
string | No | Change domain options related to tracking |
subject |
string | No | Message subject |
text |
string | No | Body of the message. (text version) |
html |
string | No | Body of the message. (html version) |
o:tag |
string | No | Tag string for message tagging. Repeat the parameter multiple times to add multiple tags. |
recipient-variables |
string | No | Recipient variables allow you to personalize individual messages by passing variables for multiple recipients in a JSON structure |
Responses
OK
Code Samples
curl -X POST 'https://zap-api.omnivery.net/{domain}/messages' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY' \
-d '{"reply_to": {{reply_to}}, "to": {{to}}, "inline": "string", "bcc": {{bcc}}, "callback_url": https://webhook.site/eee14325-defd-4088-86cd-d67d4bd6f9b3, "domain": "string", "h:X-Mailgun-Variables": {"title": "API documentation", "body": "Sending messages with templates"}, "o:tracking-opens": no, "h:Test": randomtexthere, "o:testmode": true, "template": filename.html, "template_variables": { "heading":"Sample heading", "cta":{"link":"https://example.com","title":"Link description"}}, "v:chars": ěščřžýáíéĚŠČŘŽÝÁÍÉÍ, "v:fname": Jakub, "v:link.url": "string", "o:tracking": no, "amp-html": "string", "attachment": "string", "cc": {{cc}}, "from": {{from}}, "o:tracking-clicks": yes, "subject": {{subject}}, "text": Sample %recipient.fname% plain text body
Check out www.mailkit.com or omnivery.com or https://omnivery.com, "html": <html><body>Hi %recipient.fname%, Here's the body 😒 with more +ěščíáýžšěčíě UTF %recipient.chars%. And a fancy <a href="%recipient.url.link%">%recipient.url.title%!</a>
<div><!--[if mso]>
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="%recipient.url.link%" style="height:40px;v-text-anchor:middle;width:200px;" arcsize="10%" strokecolor="#1e3650" fill="t">
<v:fill type="tile" src="https://i.imgur.com/0xPEf.gif" color="#556270" />
<w:anchorlock/>
<center style="color:#ffffff;font-family:sans-serif;font-size:13px;font-weight:bold;">Show me the button!</center>
</v:roundrect>
<![endif]--><a href="%recipient.url.link%"
style="background-color:#556270;background-image:url(https://i.imgur.com/0xPEf.gif);border:1px solid #1e3650;border-radius:4px;color:#ffffff;display:inline-block;font-family:sans-serif;font-size:13px;font-weight:bold;line-height:40px;text-align:center;text-decoration:none;width:200px;-webkit-text-size-adjust:none;mso-hide:all;">Show me the button!</a></div></body></html>, "o:tag": Test, "recipient-variables": {"jakub.olexa@omnivery.com": {"fname":"Jakub","chars":"ěščřžýáíéĚŠČŘŽÝÁÍÉÍ","url": { "link":"//www.mailkit.com","title":"This is a link"}}}}'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://zap-api.omnivery.net/{domain}/messages", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/{domain}/messages', {
method: 'POST',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
body: JSON.stringify({"reply_to": {{reply_to}}, "to": {{to}}, "inline": "string", "bcc": {{bcc}}, "callback_url": https://webhook.site/eee14325-defd-4088-86cd-d67d4bd6f9b3, "domain": "string", "h:X-Mailgun-Variables": {"title": "API documentation", "body": "Sending messages with templates"}, "o:tracking-opens": no, "h:Test": randomtexthere, "o:testmode": true, "template": filename.html, "template_variables": { "heading":"Sample heading", "cta":{"link":"https://example.com","title":"Link description"}}, "v:chars": ěščřžýáíéĚŠČŘŽÝÁÍÉÍ, "v:fname": Jakub, "v:link.url": "string", "o:tracking": no, "amp-html": "string", "attachment": "string", "cc": {{cc}}, "from": {{from}}, "o:tracking-clicks": yes, "subject": {{subject}}, "text": Sample %recipient.fname% plain text body
Check out www.mailkit.com or omnivery.com or https://omnivery.com, "html": <html><body>Hi %recipient.fname%, Here's the body 😒 with more +ěščíáýžšěčíě UTF %recipient.chars%. And a fancy <a href="%recipient.url.link%">%recipient.url.title%!</a>
<div><!--[if mso]>
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="%recipient.url.link%" style="height:40px;v-text-anchor:middle;width:200px;" arcsize="10%" strokecolor="#1e3650" fill="t">
<v:fill type="tile" src="https://i.imgur.com/0xPEf.gif" color="#556270" />
<w:anchorlock/>
<center style="color:#ffffff;font-family:sans-serif;font-size:13px;font-weight:bold;">Show me the button!</center>
</v:roundrect>
<![endif]--><a href="%recipient.url.link%"
style="background-color:#556270;background-image:url(https://i.imgur.com/0xPEf.gif);border:1px solid #1e3650;border-radius:4px;color:#ffffff;display:inline-block;font-family:sans-serif;font-size:13px;font-weight:bold;line-height:40px;text-align:center;text-decoration:none;width:200px;-webkit-text-size-adjust:none;mso-hide:all;">Show me the button!</a></div></body></html>, "o:tag": Test, "recipient-variables": {"jakub.olexa@omnivery.com": {"fname":"Jakub","chars":"ěščřžýáíéĚŠČŘŽÝÁÍÉÍ","url": { "link":"//www.mailkit.com","title":"This is a link"}}}})
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/{domain}/messages');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"reply_to": {{reply_to}}, "to": {{to}}, "inline": "string", "bcc": {{bcc}}, "callback_url": https://webhook.site/eee14325-defd-4088-86cd-d67d4bd6f9b3, "domain": "string", "h:X-Mailgun-Variables": {"title": "API documentation", "body": "Sending messages with templates"}, "o:tracking-opens": no, "h:Test": randomtexthere, "o:testmode": true, "template": filename.html, "template_variables": { "heading":"Sample heading", "cta":{"link":"https://example.com","title":"Link description"}}, "v:chars": ěščřžýáíéĚŠČŘŽÝÁÍÉÍ, "v:fname": Jakub, "v:link.url": "string", "o:tracking": no, "amp-html": "string", "attachment": "string", "cc": {{cc}}, "from": {{from}}, "o:tracking-clicks": yes, "subject": {{subject}}, "text": Sample %recipient.fname% plain text body
Check out www.mailkit.com or omnivery.com or https://omnivery.com, "html": <html><body>Hi %recipient.fname%, Here's the body 😒 with more +ěščíáýžšěčíě UTF %recipient.chars%. And a fancy <a href="%recipient.url.link%">%recipient.url.title%!</a>
<div><!--[if mso]>
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="%recipient.url.link%" style="height:40px;v-text-anchor:middle;width:200px;" arcsize="10%" strokecolor="#1e3650" fill="t">
<v:fill type="tile" src="https://i.imgur.com/0xPEf.gif" color="#556270" />
<w:anchorlock/>
<center style="color:#ffffff;font-family:sans-serif;font-size:13px;font-weight:bold;">Show me the button!</center>
</v:roundrect>
<![endif]--><a href="%recipient.url.link%"
style="background-color:#556270;background-image:url(https://i.imgur.com/0xPEf.gif);border:1px solid #1e3650;border-radius:4px;color:#ffffff;display:inline-block;font-family:sans-serif;font-size:13px;font-weight:bold;line-height:40px;text-align:center;text-decoration:none;width:200px;-webkit-text-size-adjust:none;mso-hide:all;">Show me the button!</a></div></body></html>, "o:tag": Test, "recipient-variables": {"jakub.olexa@omnivery.com": {"fname":"Jakub","chars":"ěščřžýáíéĚŠČŘŽÝÁÍÉÍ","url": { "link":"//www.mailkit.com","title":"This is a link"}}}}');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.post(
'https://zap-api.omnivery.net/{domain}/messages',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
json={"reply_to": {{reply_to}}, "to": {{to}}, "inline": "string", "bcc": {{bcc}}, "callback_url": https://webhook.site/eee14325-defd-4088-86cd-d67d4bd6f9b3, "domain": "string", "h:X-Mailgun-Variables": {"title": "API documentation", "body": "Sending messages with templates"}, "o:tracking-opens": no, "h:Test": randomtexthere, "o:testmode": true, "template": filename.html, "template_variables": { "heading":"Sample heading", "cta":{"link":"https://example.com","title":"Link description"}}, "v:chars": ěščřžýáíéĚŠČŘŽÝÁÍÉÍ, "v:fname": Jakub, "v:link.url": "string", "o:tracking": no, "amp-html": "string", "attachment": "string", "cc": {{cc}}, "from": {{from}}, "o:tracking-clicks": yes, "subject": {{subject}}, "text": Sample %recipient.fname% plain text body
Check out www.mailkit.com or omnivery.com or https://omnivery.com, "html": <html><body>Hi %recipient.fname%, Here's the body 😒 with more +ěščíáýžšěčíě UTF %recipient.chars%. And a fancy <a href="%recipient.url.link%">%recipient.url.title%!</a>
<div><!--[if mso]>
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="%recipient.url.link%" style="height:40px;v-text-anchor:middle;width:200px;" arcsize="10%" strokecolor="#1e3650" fill="t">
<v:fill type="tile" src="https://i.imgur.com/0xPEf.gif" color="#556270" />
<w:anchorlock/>
<center style="color:#ffffff;font-family:sans-serif;font-size:13px;font-weight:bold;">Show me the button!</center>
</v:roundrect>
<![endif]--><a href="%recipient.url.link%"
style="background-color:#556270;background-image:url(https://i.imgur.com/0xPEf.gif);border:1px solid #1e3650;border-radius:4px;color:#ffffff;display:inline-block;font-family:sans-serif;font-size:13px;font-weight:bold;line-height:40px;text-align:center;text-decoration:none;width:200px;-webkit-text-size-adjust:none;mso-hide:all;">Show me the button!</a></div></body></html>, "o:tag": Test, "recipient-variables": {"jakub.olexa@omnivery.com": {"fname":"Jakub","chars":"ěščřžýáíéĚŠČŘŽÝÁÍÉÍ","url": { "link":"//www.mailkit.com","title":"This is a link"}}}}
)
print(response.json())
Response
Validates single email address
WARNING: Email Validation uses 3rd party validation service by Kickbox. Using email validation will result in personal information being transferred to a 3rd party. To prevent any mistakes, the validation must be allowed in the domain settings first.
Succesfull response data:
- result string - The verification result: deliverable, undeliverable, risky, unknown
- reason string - The reason for the result. Possible reasons are:
- invalid_email - Specified email is not a valid email address syntax
- invalid_domain - Domain for email does not exist
- rejected_email - Email address was rejected by the SMTP server, email address does not exist
- accepted_email - Email address was accepted by the SMTP server
- low_quality - Email address has quality issues that may make it a risky or low-value address
- low_deliverability - Email address appears to be deliverable, but deliverability cannot be guaranteed
- no_connect - Could not connect to SMTP server
- timeout - SMTP session timed out
- invalid_smtp - SMTP server returned an unexpected/invalid response
- unavailable_smtp - SMTP server was unavailable to process our request
- unexpected_error - An unexpected error has occurred
- role true | false - true if the email address is a role address (postmaster@example.com, support@example.com, etc)
- free true | false - true if the email address uses a free email service like gmail.com or yahoo.com.
- disposable true | false - true if the email address uses a disposable domain like trashmail.com or mailinator.com.
- accept_all true | false - true if the email was accepted, but the domain appears to accept all emails addressed to that domain.
- did_you_mean null | string - Returns a suggested email if a possible spelling error was detected. (bill.lumbergh@gamil.com -> bill.lumbergh@gmail.com)
- sendex float - A quality score of the provided email address ranging between 0 (no quality) and 1 (perfect quality). More information on the Sendex Score can be found here.
- email string - Returns a normalized version of the provided email address. (BoB@example.com -> bob@example.com)
Regarding Email Normalization
It is important to note that a normalized email address is a functional equivalent to the submitted email address. You may want to log the email address as-is before being submitted to the API for record keeping purposes.
- user string - The user (a.k.a local part) of the provided email address. (bob@example.com -> bob)
- domain string - The domain of the provided email address. (bob@example.com -> example.com)
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
address |
query | string | No | Email address to be validated |
domain |
path | string | Yes | Domain to be used for validation |
Responses
OK
{
"accept_all": false,
"did_you_mean": null,
"disposable": false,
"domain": "wildwest.org",
"email": "janedoe@wildwest.org",
"free": false,
"message": null,
"reason": "unexpected_error",
"result": "unknown",
"role": false,
"sendex": 0.6,
"success": true,
"timeLogged": 1658471901,
"user": "janedoe"
}
Code Samples
curl -X GET 'https://zap-api.omnivery.net/{domain}/validate' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://zap-api.omnivery.net/{domain}/validate", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/{domain}/validate', {
method: 'GET',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/{domain}/validate');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.get(
'https://zap-api.omnivery.net/{domain}/validate',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
)
print(response.json())
Response
Add a record to the domain suppression list list.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain |
path | string | Yes | Domain for the suppression to be stored at |
Request Body multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
address |
string | No | Valid email address |
error |
string | No | Unsubscribe reason or description (optional) |
type |
string | No | Suppression type |
Responses
Successful response
Code Samples
curl -X POST 'https://zap-api.omnivery.net/{domain}/suppress' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY' \
-d '{"address": sample@example.org, "error": Some text, "type": complaint}'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://zap-api.omnivery.net/{domain}/suppress", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/{domain}/suppress', {
method: 'POST',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
body: JSON.stringify({"address": sample@example.org, "error": Some text, "type": complaint})
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/{domain}/suppress');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"address": sample@example.org, "error": Some text, "type": complaint}');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.post(
'https://zap-api.omnivery.net/{domain}/suppress',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
json={"address": sample@example.org, "error": Some text, "type": complaint}
)
print(response.json())
Response
Parse email address strings and lists into objects with distinct address and name.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
addresses |
query | string | No | String containing addresses to be parsed |
Responses
OK
{
"parsed": [
{
"domain": "example.com",
"email": "johndoe@example.com",
"localpart": "johndoe"
},
{
"domain": "wildwest.org",
"email": "jane.doe@wildwest.org",
"localpart": "jane.doe"
}
],
"unparseable": []
}
Code Samples
curl -X GET 'https://zap-api.omnivery.net/address/parse' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://zap-api.omnivery.net/address/parse", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/address/parse', {
method: 'GET',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/address/parse');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.get(
'https://zap-api.omnivery.net/address/parse',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
)
print(response.json())
Response
General
Returns an array listing of domains available using the current token.
The list contains information about each domain available using your current credentials. If you are using account level API key the list will contain all domains in the account. For domain level API key only the domain the key is associated with will be returned. Only domains with active state can be used for sending and receiving.
Responses
OK
[
{
"cid": 123,
"created_at": "Thu, 21 Jul 2021 01:00:00 GMT",
"data_location": "eu1",
"force_dkim_authority": false,
"id": 123,
"name": "sample.emaildemos.com",
"state": "active",
"wildcard": false
}
]
Code Samples
curl -X GET 'https://zap-api.omnivery.net/domains' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://zap-api.omnivery.net/domains", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/domains', {
method: 'GET',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/domains');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.get(
'https://zap-api.omnivery.net/domains',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
)
print(response.json())
Response
Returns the detailed information about the given domain, optionally with DNS record settings.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dns |
query | boolean | No | Get DNS records for domain |
Responses
Compact detail
{
"domain": {
"channel": "email",
"created_at": "Mon, 14 Mar 2022 16:40:47 GMT",
"data_location": "eu1",
"dkim_auth": true,
"limit": "5000/86400",
"name": "notify.omnivery.com",
"seedmail": "seed-319432f0fdddae692eff3ec038405678@notify.omnivery.com",
"state": "active",
"transactional": true,
"updated_at": "Sat, 30 Sep 2023 15:56:39 GMT",
"wildcard": false
}
}
Code Samples
curl -X GET 'https://zap-api.omnivery.net/domains/{domain}' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://zap-api.omnivery.net/domains/{domain}", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/domains/{domain}', {
method: 'GET',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/domains/{domain}');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.get(
'https://zap-api.omnivery.net/domains/{domain}',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
)
print(response.json())
Response
Performs connection test to validate authentication.
Responses
OK
{
"auth": {
"cid": 123,
"did": 123,
"domain": "sample.emaildemos.com",
"role": "sending",
"tid": 123
}
}
Code Samples
curl -X GET 'https://zap-api.omnivery.net/test' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://zap-api.omnivery.net/test", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/test', {
method: 'GET',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/test');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.get(
'https://zap-api.omnivery.net/test',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
)
print(response.json())
Response
Webhooks
Deletes an existing webhook and URL endpoints assigned.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain |
path | string | Yes | Domain to remove webhook from |
webhooktype |
path | string | Yes |
Responses
OK
{
"message": "Webhook has been deleted"
}
Payment Required
{
"message": "No webhooks deleted"
}
Code Samples
curl -X DELETE 'https://zap-api.omnivery.net/domains/{domain}/webhooks/{webhooktype}' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://zap-api.omnivery.net/domains/{domain}/webhooks/{webhooktype}", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/domains/{domain}/webhooks/{webhooktype}', {
method: 'DELETE',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/domains/{domain}/webhooks/{webhooktype}');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.delete(
'https://zap-api.omnivery.net/domains/{domain}/webhooks/{webhooktype}',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
)
print(response.json())
Response
Creates a new webhook. Note When adding a Clicked or Opened webhook, ensure that you also have tracking enabled.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain |
path | string | Yes | Domain to add webhook to |
Request Body multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | No | Type of the webhook |
url |
string | No | URL for the webhook event. May be repeated up to 3 times. |
Responses
Payment Required
{
"errors": [
"URL endpoint failed with error 404 - Not Found"
]
}
OK
{
"message": "Webhook has been updated",
"webhook": {
"urls": [
"https://www.service.com/webhook/endpoint"
]
}
}
Code Samples
curl -X POST 'https://zap-api.omnivery.net/domains/{domain}/webhooks' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY' \
-d '{"id": {{webhooktype}}, "url": https://www.mailkit.com/}'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://zap-api.omnivery.net/domains/{domain}/webhooks", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/domains/{domain}/webhooks', {
method: 'POST',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
body: JSON.stringify({"id": {{webhooktype}}, "url": https://www.mailkit.com/})
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/domains/{domain}/webhooks');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"id": {{webhooktype}}, "url": https://www.mailkit.com/}');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.post(
'https://zap-api.omnivery.net/domains/{domain}/webhooks',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
json={"id": {{webhooktype}}, "url": https://www.mailkit.com/}
)
print(response.json())
Response
Returns sample data produced by the webhook.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain |
path | string | Yes | Domain to be used for testing webhook |
webhooktype |
path | string | Yes | Type of webhook test post to be performed |
Responses
OK
[
{
"event-data": {
"delivery-status": {
"code": 250,
"description": "250 2.0.0 Ok: queued as E15E2203D4",
"message": [
"Ok: queued as E15E2203D4"
],
"mx-host": "mx.example.com",
"mx-ip": "254.254.254.254",
"tls": true
},
"envelope": {
"sender": "prvs=07802bad8b=01f6m6bqcwmjkpbm8xmecbnq8h@ov.zapier.emaildemos.com",
"sending-ip": "127.0.1.2",
"targets": "johndoe@example.com",
"transport": "smtp"
},
"message": {
"headers": {
"date": "Thu, 1 Apr 2021 11:11:11 +0000",
"from": "Tester \u003ctester@zapier.emaildemos.com\u003e",
"subject": "Webhook testing",
"to": "\"John Doe\" \u003cjohndoe@example.com\u003e",
"x-mailer": "Omnivery MG API 0.1",
"x-testid": "1234"
},
"size": 3912
},
"recipient": "johndoe@example.com",
"recipient-domain": "example.com",
"tags": [
"MyTag1",
"MyTag2"
],
"timestamp": 1617268271
},
"signature": {
"signature": "871fbe30773b3a06638cae7f9b210e272c47eb11ed186d3a871a811de3d212f8",
"timestamp": 1658470909,
"token": "7b92b915375a216d5777015a6dbb7670"
}
}
]
Code Samples
curl -X GET 'https://zap-api.omnivery.net/domains/{domain}/webhooks/{webhooktype}/sample' \
-H 'Content-Type: application/json' \
-H 'ov-token: YOUR_API_KEY'
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://zap-api.omnivery.net/domains/{domain}/webhooks/{webhooktype}/sample", nil)
req.Header.Set("ov-token", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
fmt.Println(resp.Status)
}
const response = await fetch('https://zap-api.omnivery.net/domains/{domain}/webhooks/{webhooktype}/sample', {
method: 'GET',
headers: {'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
});
const data = await response.json();
<?php
$ch = curl_init('https://zap-api.omnivery.net/domains/{domain}/webhooks/{webhooktype}/sample');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['ov-token: YOUR_API_KEY']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests
response = requests.get(
'https://zap-api.omnivery.net/domains/{domain}/webhooks/{webhooktype}/sample',
headers={'Content-Type': 'application/json', 'ov-token': 'YOUR_API_KEY'},
)
print(response.json())