> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer.jelliu.co/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.jelliu.co/_mcp/server.

# Check whether a number may be contacted now

POST https://api.jelliu.co/api/compliance/check-call
Content-Type: application/json

Runs the same gate that every outbound call, WhatsApp send and campaign email passes before it leaves, and
reports whether contacting `phoneNumber` is allowed **right now** and, if not, why. Nothing is dialed or sent.

The country comes from the number's prefix: `+57` CO, `+52` MX, `+55` BR, `+1` US (this includes Canada and
the Caribbean), `+54` AR, `+56` CL, `+51` PE. Any other prefix uses a generic default: 08:00–20:00, 3 attempts
per day, 10 in total, DNC check on. The effective rules are the workspace's saved config for that country, or
the country defaults. Checks run in this order, and the first failure is returned:

1. **Allowed call hours.** When the workspace has a time zone in its settings, that time zone replaces the
   country's. The generic default uses `America/Bogota` when no time zone is set. The end time is exclusive.
2. **Blocked prefixes.**
3. **Suppression list.** Exact E.164 match, checked whatever `require_dnc_check` says.
4. **The contact's DNC status**, when `contactId` is given.
5. **DNC by phone number.** Any contact in the workspace with this phone or WhatsApp number marked
   do-not-call. Runs only when `require_dnc_check` is on.
6. **Daily attempt limit**, when `contactId` is given. Counts the contact's call rows since local midnight.
7. **Total attempt limit**, when `contactId` is given. Uses the contact's `call_attempts` counter.

Consent records are not part of this check. `require_opt_in` is stored on configs but is not enforced here.
To test consent, use `GET /api/compliance/consent/check/{contactId}/{consentType}`.

The answer is only valid for the moment it is computed. Hours and attempt counts change, so the real send
re-checks.

**Side effects.** None. This is a read, but it is a POST, so API keys need `write`.

**Idempotency.** Safe to retry. The answer can change over time, as described above.

**Access**

* **Required scope:** `write`. Any signed-in workspace role.
* **Rate limit:** General API — 120 (Starter), 200 (Growth), 300 (Business) or 600 (Enterprise) requests/min per workspace. See [Rate limits](/rate-limits).
* **Plan:** Available on every plan.

Reference: https://developer.jelliu.co/api-reference/compliance/post-compliance-check-call

## Authentication

- `Authorization` header (bearer token, required) — Workspace API key: `jl_` followed by 64 lowercase hex characters, created by the workspace owner in the dashboard (**Settings → API Keys**) and sent as `Authorization: Bearer jl_...`. The plaintext is shown once, at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys. | Scope | GET / HEAD | POST / PUT / PATCH / DELETE | Admin-only routes | | --- | --- | --- | --- | | `read` | Yes | No | No | | `write` | Yes | Yes | No | | `full` | Yes | Yes | Yes | Operations restricted to admins or owners reject keys without the `full` scope with `403`, and say so in their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret — that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds. See [Authentication](/authentication).

## Request

### Body (application/json)

This endpoint expects an object.

- `phoneNumber` (string, required) — The number to check, in E.164 format with no spaces or dashes. It decides the country and is matched against the suppression list and DNC contacts.
- `contactId` (string, optional) — The contact being reached. Enables the contact DNC check and both attempt-limit checks.

## Response

### 200

Whether contact is allowed and, if not, why.

- `data` (object, required) — The outcome of the outbound compliance gate.
  - `allowed` (boolean, required) — `true` when every check passed.
  - `reason` (string, optional) — Present only when `allowed` is `false`. Names the first check that failed. Possible values: * `Outside allowed call hours (<start>-<end> <timezone>)` * `Phone number matches blocked prefix: <prefix>` * `Phone number is on the opt-out suppression list` * `Contact is on the Do Not Call list` * `Phone number is on the Do Not Call list` * `Max daily call attempts reached (<n>/day)` * `Max total call attempts reached (<n> total)`

## Errors

### 400 Bad Request Error

The body failed validation. `details` is the flattened Zod error.

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 401 Unauthorized Error

No usable credential. Either the `Authorization` header is missing or is not a well-formed `Bearer jl_…` key, or the key is unknown, revoked or expired. Do not retry with the same key. See [Authentication](/authentication#401-unauthorized).

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 403 Forbidden Error

The API key lacks the `write` scope, or the workspace is suspended.

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 429 Too Many Requests Error

Rate limit exceeded for the current 60-second window (`RATE_LIMIT_EXCEEDED`). Wait `Retry-After` seconds, then retry. The `message` differs per limiter; the code does not. See [Rate limits](/rate-limits).

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

## Examples

### Allowed

**Request**

```json
undefined
```

**Response**

```json
{
  "data": {
    "allowed": true
  }
}
```

**SDK Code**

```python Allowed
import requests

url = "https://api.jelliu.co/api/compliance/check-call"

headers = {"Authorization": "Bearer <token>"}

response = requests.post(url, headers=headers)

print(response.json())
```

```javascript Allowed
const url = 'https://api.jelliu.co/api/compliance/check-call';
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Allowed
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/compliance/check-call"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Allowed
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/compliance/check-call")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java Allowed
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/compliance/check-call")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Allowed
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/compliance/check-call', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp Allowed
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/compliance/check-call");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Allowed
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/compliance/check-call")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Outside allowed hours

**Request**

```json
undefined
```

**Response**

```json
{
  "data": {
    "allowed": false,
    "reason": "Outside allowed call hours (08:00-20:00 America/Bogota)"
  }
}
```

**SDK Code**

```python Outside allowed hours
import requests

url = "https://api.jelliu.co/api/compliance/check-call"

headers = {"Authorization": "Bearer <token>"}

response = requests.post(url, headers=headers)

print(response.json())
```

```javascript Outside allowed hours
const url = 'https://api.jelliu.co/api/compliance/check-call';
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Outside allowed hours
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/compliance/check-call"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Outside allowed hours
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/compliance/check-call")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java Outside allowed hours
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/compliance/check-call")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Outside allowed hours
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/compliance/check-call', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp Outside allowed hours
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/compliance/check-call");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Outside allowed hours
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/compliance/check-call")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### On the suppression list

**Request**

```json
undefined
```

**Response**

```json
{
  "data": {
    "allowed": false,
    "reason": "Phone number is on the opt-out suppression list"
  }
}
```

**SDK Code**

```python On the suppression list
import requests

url = "https://api.jelliu.co/api/compliance/check-call"

headers = {"Authorization": "Bearer <token>"}

response = requests.post(url, headers=headers)

print(response.json())
```

```javascript On the suppression list
const url = 'https://api.jelliu.co/api/compliance/check-call';
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go On the suppression list
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/compliance/check-call"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby On the suppression list
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/compliance/check-call")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java On the suppression list
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/compliance/check-call")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php On the suppression list
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/compliance/check-call', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp On the suppression list
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/compliance/check-call");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift On the suppression list
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/compliance/check-call")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Daily attempt limit reached

**Request**

```json
undefined
```

**Response**

```json
{
  "data": {
    "allowed": false,
    "reason": "Max daily call attempts reached (3/day)"
  }
}
```

**SDK Code**

```python Daily attempt limit reached
import requests

url = "https://api.jelliu.co/api/compliance/check-call"

headers = {"Authorization": "Bearer <token>"}

response = requests.post(url, headers=headers)

print(response.json())
```

```javascript Daily attempt limit reached
const url = 'https://api.jelliu.co/api/compliance/check-call';
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Daily attempt limit reached
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/compliance/check-call"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Daily attempt limit reached
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/compliance/check-call")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java Daily attempt limit reached
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/compliance/check-call")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Daily attempt limit reached
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/compliance/check-call', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp Daily attempt limit reached
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/compliance/check-call");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Daily attempt limit reached
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/compliance/check-call")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Number only (hours, prefixes, suppression, DNC)

**Request**

```json
{
  "phoneNumber": "+13055550142"
}
```

**Response**

```json
{
  "data": {
    "allowed": true
  }
}
```

**SDK Code**

```python Number only (hours, prefixes, suppression, DNC)
import requests

url = "https://api.jelliu.co/api/compliance/check-call"

payload = { "phoneNumber": "+13055550142" }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Number only (hours, prefixes, suppression, DNC)
const url = 'https://api.jelliu.co/api/compliance/check-call';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"phoneNumber":"+13055550142"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Number only (hours, prefixes, suppression, DNC)
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/compliance/check-call"

	payload := strings.NewReader("{\n  \"phoneNumber\": \"+13055550142\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Number only (hours, prefixes, suppression, DNC)
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/compliance/check-call")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"phoneNumber\": \"+13055550142\"\n}"

response = http.request(request)
puts response.read_body
```

```java Number only (hours, prefixes, suppression, DNC)
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/compliance/check-call")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"phoneNumber\": \"+13055550142\"\n}")
  .asString();
```

```php Number only (hours, prefixes, suppression, DNC)
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/compliance/check-call', [
  'body' => '{
  "phoneNumber": "+13055550142"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Number only (hours, prefixes, suppression, DNC)
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/compliance/check-call");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"phoneNumber\": \"+13055550142\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Number only (hours, prefixes, suppression, DNC)
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["phoneNumber": "+13055550142"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/compliance/check-call")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Number and contact (adds the attempt limits)

**Request**

```json
{
  "phoneNumber": "+573001234567",
  "contactId": "3f6c1a2e-8d4b-4c7a-9e21-5b7d0c9a4e18"
}
```

**Response**

```json
{
  "data": {
    "allowed": true
  }
}
```

**SDK Code**

```python Number and contact (adds the attempt limits)
import requests

url = "https://api.jelliu.co/api/compliance/check-call"

payload = {
    "phoneNumber": "+573001234567",
    "contactId": "3f6c1a2e-8d4b-4c7a-9e21-5b7d0c9a4e18"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Number and contact (adds the attempt limits)
const url = 'https://api.jelliu.co/api/compliance/check-call';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"phoneNumber":"+573001234567","contactId":"3f6c1a2e-8d4b-4c7a-9e21-5b7d0c9a4e18"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Number and contact (adds the attempt limits)
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/compliance/check-call"

	payload := strings.NewReader("{\n  \"phoneNumber\": \"+573001234567\",\n  \"contactId\": \"3f6c1a2e-8d4b-4c7a-9e21-5b7d0c9a4e18\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Number and contact (adds the attempt limits)
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/compliance/check-call")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"phoneNumber\": \"+573001234567\",\n  \"contactId\": \"3f6c1a2e-8d4b-4c7a-9e21-5b7d0c9a4e18\"\n}"

response = http.request(request)
puts response.read_body
```

```java Number and contact (adds the attempt limits)
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/compliance/check-call")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"phoneNumber\": \"+573001234567\",\n  \"contactId\": \"3f6c1a2e-8d4b-4c7a-9e21-5b7d0c9a4e18\"\n}")
  .asString();
```

```php Number and contact (adds the attempt limits)
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/compliance/check-call', [
  'body' => '{
  "phoneNumber": "+573001234567",
  "contactId": "3f6c1a2e-8d4b-4c7a-9e21-5b7d0c9a4e18"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Number and contact (adds the attempt limits)
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/compliance/check-call");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"phoneNumber\": \"+573001234567\",\n  \"contactId\": \"3f6c1a2e-8d4b-4c7a-9e21-5b7d0c9a4e18\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Number and contact (adds the attempt limits)
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "phoneNumber": "+573001234567",
  "contactId": "3f6c1a2e-8d4b-4c7a-9e21-5b7d0c9a4e18"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/compliance/check-call")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```