curl --request POST \
--url https://api.croma.run/monitors \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Contrato AD9-111",
"endpoint": "/co/anm/notices-search/v1",
"query": {
"title_number": "AD9-111"
},
"schedule": {
"cadence": "source"
},
"recipients": [
"legal@example.com"
],
"notify": "always",
"language": "es"
}
'import requests
url = "https://api.croma.run/monitors"
payload = {
"name": "Contrato AD9-111",
"endpoint": "/co/anm/notices-search/v1",
"query": { "title_number": "AD9-111" },
"schedule": { "cadence": "source" },
"recipients": ["legal@example.com"],
"notify": "always",
"language": "es"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Contrato AD9-111',
endpoint: '/co/anm/notices-search/v1',
query: {title_number: 'AD9-111'},
schedule: {cadence: 'source'},
recipients: ['legal@example.com'],
notify: 'always',
language: 'es'
})
};
fetch('https://api.croma.run/monitors', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.croma.run/monitors",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Contrato AD9-111',
'endpoint' => '/co/anm/notices-search/v1',
'query' => [
'title_number' => 'AD9-111'
],
'schedule' => [
'cadence' => 'source'
],
'recipients' => [
'legal@example.com'
],
'notify' => 'always',
'language' => 'es'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.croma.run/monitors"
payload := strings.NewReader("{\n \"name\": \"Contrato AD9-111\",\n \"endpoint\": \"/co/anm/notices-search/v1\",\n \"query\": {\n \"title_number\": \"AD9-111\"\n },\n \"schedule\": {\n \"cadence\": \"source\"\n },\n \"recipients\": [\n \"legal@example.com\"\n ],\n \"notify\": \"always\",\n \"language\": \"es\"\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(string(body))
}HttpResponse<String> response = Unirest.post("https://api.croma.run/monitors")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Contrato AD9-111\",\n \"endpoint\": \"/co/anm/notices-search/v1\",\n \"query\": {\n \"title_number\": \"AD9-111\"\n },\n \"schedule\": {\n \"cadence\": \"source\"\n },\n \"recipients\": [\n \"legal@example.com\"\n ],\n \"notify\": \"always\",\n \"language\": \"es\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.croma.run/monitors")
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 \"name\": \"Contrato AD9-111\",\n \"endpoint\": \"/co/anm/notices-search/v1\",\n \"query\": {\n \"title_number\": \"AD9-111\"\n },\n \"schedule\": {\n \"cadence\": \"source\"\n },\n \"recipients\": [\n \"legal@example.com\"\n ],\n \"notify\": \"always\",\n \"language\": \"es\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "mon_5f1c2c0a-9d1e-4a3b-8c7d-1e2f3a4b5c6d",
"name": "<string>",
"endpoint": {
"id": "anm-notices-search",
"path": "/co/anm/notices-search/v1",
"source": "ANM",
"name": "<string>"
},
"query": {},
"relevance": "<string>",
"schedule": {
"cadence": "source",
"timezone": "<string>",
"cron": "30 7 * * *",
"next_run_at": "2023-11-07T05:31:56Z",
"at": "<string>",
"weekday": "monday"
},
"recipients": [
"<string>"
],
"notify": "always",
"language": "es",
"status": "active",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"last_run": {
"id": "<string>",
"at": "2023-11-07T05:31:56Z",
"status": "running",
"new_results": 123,
"relevant_results": 123,
"source_as_of": "<string>",
"source_stale": true
}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"details": {}
}
}Create Monitor
Watch a dataset endpoint on a schedule and email up to three addresses what is new. The monitor runs once right away to record what already matches (the baseline) and sends a welcome email; from then on every run reports only rows that appeared since the last one. With schedule.cadence: "source" (the default) each run starts after the dataset’s own refresh has completed, so a daily source is checked once a day, right after new data lands. Each run spends the same credits as one request to the endpoint. An organization may have up to 20 monitors.
curl --request POST \
--url https://api.croma.run/monitors \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Contrato AD9-111",
"endpoint": "/co/anm/notices-search/v1",
"query": {
"title_number": "AD9-111"
},
"schedule": {
"cadence": "source"
},
"recipients": [
"legal@example.com"
],
"notify": "always",
"language": "es"
}
'import requests
url = "https://api.croma.run/monitors"
payload = {
"name": "Contrato AD9-111",
"endpoint": "/co/anm/notices-search/v1",
"query": { "title_number": "AD9-111" },
"schedule": { "cadence": "source" },
"recipients": ["legal@example.com"],
"notify": "always",
"language": "es"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Contrato AD9-111',
endpoint: '/co/anm/notices-search/v1',
query: {title_number: 'AD9-111'},
schedule: {cadence: 'source'},
recipients: ['legal@example.com'],
notify: 'always',
language: 'es'
})
};
fetch('https://api.croma.run/monitors', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.croma.run/monitors",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Contrato AD9-111',
'endpoint' => '/co/anm/notices-search/v1',
'query' => [
'title_number' => 'AD9-111'
],
'schedule' => [
'cadence' => 'source'
],
'recipients' => [
'legal@example.com'
],
'notify' => 'always',
'language' => 'es'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.croma.run/monitors"
payload := strings.NewReader("{\n \"name\": \"Contrato AD9-111\",\n \"endpoint\": \"/co/anm/notices-search/v1\",\n \"query\": {\n \"title_number\": \"AD9-111\"\n },\n \"schedule\": {\n \"cadence\": \"source\"\n },\n \"recipients\": [\n \"legal@example.com\"\n ],\n \"notify\": \"always\",\n \"language\": \"es\"\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(string(body))
}HttpResponse<String> response = Unirest.post("https://api.croma.run/monitors")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Contrato AD9-111\",\n \"endpoint\": \"/co/anm/notices-search/v1\",\n \"query\": {\n \"title_number\": \"AD9-111\"\n },\n \"schedule\": {\n \"cadence\": \"source\"\n },\n \"recipients\": [\n \"legal@example.com\"\n ],\n \"notify\": \"always\",\n \"language\": \"es\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.croma.run/monitors")
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 \"name\": \"Contrato AD9-111\",\n \"endpoint\": \"/co/anm/notices-search/v1\",\n \"query\": {\n \"title_number\": \"AD9-111\"\n },\n \"schedule\": {\n \"cadence\": \"source\"\n },\n \"recipients\": [\n \"legal@example.com\"\n ],\n \"notify\": \"always\",\n \"language\": \"es\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "mon_5f1c2c0a-9d1e-4a3b-8c7d-1e2f3a4b5c6d",
"name": "<string>",
"endpoint": {
"id": "anm-notices-search",
"path": "/co/anm/notices-search/v1",
"source": "ANM",
"name": "<string>"
},
"query": {},
"relevance": "<string>",
"schedule": {
"cadence": "source",
"timezone": "<string>",
"cron": "30 7 * * *",
"next_run_at": "2023-11-07T05:31:56Z",
"at": "<string>",
"weekday": "monday"
},
"recipients": [
"<string>"
],
"notify": "always",
"language": "es",
"status": "active",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"last_run": {
"id": "<string>",
"at": "2023-11-07T05:31:56Z",
"status": "running",
"new_results": 123,
"relevant_results": 123,
"source_as_of": "<string>",
"source_stale": true
}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"details": {}
}
}Authorizations
Use Authorization: Bearer YOUR_API_KEY
Headers
Optional client-chosen key for this request (any string up to 255 characters, e.g. a UUID). Every Croma operation is an idempotent lookup: repeating a request with the same body returns the same result and creates nothing, so retrying after a timeout or network failure is always safe. The key is echoed back in the Idempotency-Key response header so you can correlate a retry with its first attempt. Each attempt that reaches the API counts against the rate limit.
255"0f8e9a42-6b7c-4d1e-9a3f-2c5d7e8f9a0b"
Body
1 - 120"Contrato AD9-111"
The dataset endpoint to watch, by path or catalog id. Only endpoints with monitorable: true in /catalog are accepted.
"/co/anm/notices-search/v1"
Up to three addresses that receive the results.
1 - 3 elementsThe request body the monitor sends to the endpoint, validated exactly as a direct request would be. page and per_page are not allowed.
{ "title_number": "AD9-111" }
When the monitor runs. source (the default) runs right after the dataset's own refresh completes; hourly, daily and weekly run on the clock, never faster than the source refreshes.
Show child attributes
Show child attributes
always sends an email on every run, including one that found nothing new; on_new only when there is something to report.
always, on_new Language of the emails.
es, en Optional instruction, in plain language, that filters new results by relevance before they are sent (e.g. "solo avisos sobre suspensión o caducidad del título"). Results the filter discards stay available under GET /monitors/{id}/matches?relevant=false.
500Response
The monitor, with its compiled schedule and next run.
Show child attributes
Show child attributes