https://api.atys.pro/api/v1/calendar/,
respondem JSON e têm contrato estável: mudanças incompatíveis só entram numa versão nova.
Como funciona
Tudo o que a equipe faz na Agenda da Atys também pode ser feito pela API: criar reuniões e compromissos com usuários e contatos, repetir eventos, configurar lembretes, consultar horários livres e reservar um horário em nome do cliente. Cada chamada passa pelas mesmas regras da plataforma: convites e lembretes são enviados e os eventos sincronizam com o Google Agenda ou o Outlook de quem tiver a integração ligada.
A página segue a ordem em que a Agenda é usada:
- Conhecer a agenda — tipos de evento, calendários e frequências de repetição.
- Trabalhar os eventos — listar, criar, editar, repetir, verificar conflitos e excluir.
- Participantes e lembretes — quem participa, avisos antes do evento e anexos.
- Disponibilidade e agendamento — horário de atendimento, horários livres, reservas e links públicos.
Autenticação e permissões
Use uma chave de API com as permissões da Agenda que a integração precisa:
| Permissão da chave | Libera |
|---|---|
| Consultar agenda | Todos os GET: catálogos, eventos, participantes, lembretes, anexos, horários e disponibilidade. |
| Gerenciar agenda | Criar, editar e excluir eventos, participantes, lembretes e anexos; configurar horários, reservar e gerar links. |
A chave enxerga os mesmos eventos que o usuário API enxerga na plataforma e só faz o que as permissões dele permitem (por exemplo Criar eventos e Excluir eventos).
Tipos de evento
Os tipos (reunião, ligação, lembrete, consulta…) são os mesmos para todas as empresas e mantidos pela Atys.
Use o id em type_id ao criar ou editar um evento.
Exemplos de código — listar tipos de evento
curl "https://api.atys.pro/api/v1/calendar/event-types" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/event-types', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/event-types',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/event-types');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/event-types', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/event-types", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": [
{
"id": 1,
"name": "MEETING",
"description": null
},
{
"id": 2,
"name": "CALL",
"description": null
}
]
}
Calendários
Calendários da empresa. Toda empresa nasce com um calendário principal ("default": true), que é
usado quando o evento é criado sem calendar_id. Calendários não são criados nem alterados pela API
(a plataforma também não oferece isso).
Exemplos de código — listar calendários
curl "https://api.atys.pro/api/v1/calendar/calendars" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/calendars', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/calendars',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/calendars');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/calendars', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/calendars", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": [
{
"id": 12,
"name": "AgendaPrincipal",
"description": null,
"default": true
}
]
}
Frequências de repetição
Valores aceitos em recurrence.frequency e o máximo de ocorrências que cada um gera quando a série
não tem count nem until (o mesmo limite da plataforma).
Exemplos de código — listar frequências
curl "https://api.atys.pro/api/v1/calendar/frequencies" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/frequencies', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/frequencies',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/frequencies');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/frequencies', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/frequencies", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": [
{
"value": "daily",
"name": "Diária",
"max_occurrences": 730
},
{
"value": "weekly",
"name": "Semanal",
"max_occurrences": 260
},
{
"value": "monthly",
"name": "Mensal",
"max_occurrences": 60
},
{
"value": "yearly",
"name": "Anual",
"max_occurrences": 20
}
]
}
Listar eventos
Eventos que se sobrepõem ao intervalo from–to, em ordem de início. A chave vê os mesmos
eventos que o usuário API vê na Agenda: sem a permissão Ver eventos não atribuídos, só aqueles
em que ele é participante. Cada ocorrência de uma série aparece como um evento próprio.
| Parâmetro | Tipo | Descrição |
|---|---|---|
from | data ISO 8601 | Início do intervalo. Default: hoje, 00:00, no fuso da empresa. |
to | data ISO 8601 | Fim do intervalo. Default: from + 30 dias. Máximo de 366 dias (range_too_large). |
user_ids[] | array de integer | Só eventos com algum destes usuários. |
contact_id | integer | Só eventos com este contato. |
type_id | integer | Só eventos deste tipo. |
calendar_id | integer | Só eventos deste calendário. |
origin | string | system (criado na Atys ou pela API), public_scheduling_link (reservado pelo link público ou por reservar horário) ou ai_agent. É a aba "Agendamentos pelo link" da tela. |
page, per_page | integer | Paginação; per_page de 1 a 100 (default 25). |
Exemplos de código — listar eventos
curl "https://api.atys.pro/api/v1/calendar/events?from=2026-12-01T00%3A00%3A00-03%3A00&to=2026-12-08T00%3A00%3A00-03%3A00&contact_id=5120" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/events?from=2026-12-01T00%3A00%3A00-03%3A00&to=2026-12-08T00%3A00%3A00-03%3A00&contact_id=5120', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/events?from=2026-12-01T00%3A00%3A00-03%3A00&to=2026-12-08T00%3A00%3A00-03%3A00&contact_id=5120',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events?from=2026-12-01T00%3A00%3A00-03%3A00&to=2026-12-08T00%3A00%3A00-03%3A00&contact_id=5120');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/events', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'query' => [
'from' => '2026-12-01T00:00:00-03:00',
'to' => '2026-12-08T00:00:00-03:00',
'contact_id' => 5120
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/events?from=2026-12-01T00%3A00%3A00-03%3A00&to=2026-12-08T00%3A00%3A00-03%3A00&contact_id=5120", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": [
{
"id": 4210,
"title": "Reunião de proposta",
"description": "Apresentar a proposta comercial.",
"color": "#1976d2",
"type": {
"id": 1,
"name": "MEETING"
},
"calendar_id": 12,
"start_at": "2026-12-01T10:00:00-03:00",
"end_at": "2026-12-01T11:00:00-03:00",
"time_zone": "America/Sao_Paulo",
"reminder_message": null,
"origin": "system",
"created_by": 90,
"series": null,
"users": [
{
"id": 77,
"name": "Carlos Vendedor",
"invitation_status": "accepted",
"responded_at": "2026-11-04T16:20:00-03:00"
},
{
"id": 81,
"name": "Ana Consultora",
"invitation_status": "pending",
"responded_at": null
}
],
"contacts": [
{
"id": 5120,
"name": "Maria Cliente"
}
],
"synced": {
"google": true,
"microsoft": false
},
"created_at": "2026-11-04T16:02:11-03:00",
"updated_at": "2026-11-04T16:02:11-03:00"
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 1,
"last_page": 1
}
}
Ver evento
O evento com participantes, recorrência e o estado da sincronização (synced: se já está no
Google Agenda ou no Outlook). start_at e end_at vêm no fuso do evento
(time_zone, o da empresa). Evento de outra empresa ou fora da visibilidade do usuário API responde
404.
Exemplos de código — ver evento
curl "https://api.atys.pro/api/v1/calendar/events/4210" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/events/4210',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/events/4210', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/events/4210", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"id": 4210,
"title": "Reunião de proposta",
"description": "Apresentar a proposta comercial.",
"color": "#1976d2",
"type": {
"id": 1,
"name": "MEETING"
},
"calendar_id": 12,
"start_at": "2026-12-01T10:00:00-03:00",
"end_at": "2026-12-01T11:00:00-03:00",
"time_zone": "America/Sao_Paulo",
"reminder_message": null,
"origin": "system",
"created_by": 90,
"series": null,
"users": [
{
"id": 77,
"name": "Carlos Vendedor",
"invitation_status": "accepted",
"responded_at": "2026-11-04T16:20:00-03:00"
},
{
"id": 81,
"name": "Ana Consultora",
"invitation_status": "pending",
"responded_at": null
}
],
"contacts": [
{
"id": 5120,
"name": "Maria Cliente"
}
],
"synced": {
"google": true,
"microsoft": false
},
"created_at": "2026-11-04T16:02:11-03:00",
"updated_at": "2026-11-04T16:02:11-03:00"
}
}
Criar evento
Cria o evento pela mesma rotina da tela: os usuários recebem o convite (sino e e-mail, com botões de aceitar e
recusar), os lembretes ficam agendados e, se pedido, o evento vai para o Google Agenda e/ou o Outlook do usuário
API. Sobreposição de horário não bloqueia: os choques encontrados vêm em conflicts
(mesmo formato de verificar conflitos).
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
title | string (300) | Sim | Título do evento. |
type_id | integer | Sim | Tipo do evento. |
start_at | data ISO 8601 | Sim | Início. Sem fuso no valor, vale o da empresa. |
end_at | data ISO 8601 | Sim | Fim; depois de start_at. |
user_ids | array de integer | Sim | Usuários participantes (1 a 100), da empresa (invalid_user). |
contact_ids | array de integer | Não | Contatos do evento (até 100), da empresa (invalid_contact). |
description | string | Não | Descrição. |
color | string | Não | Cor em hexadecimal, ex. #1976d2. |
calendar_id | integer | Não | Calendário; default o principal da empresa. |
reminder_message | string | Não | Mensagem personalizada que os lembretes enviam aos contatos. Aceita {{event.title}}, {{event.date}}, {{event.time}} e {{event.end_time}}. Sem ela, vai o texto padrão. |
recurrence | objeto | Não | Repete o evento: frequency (frequência), interval (a cada N, default 1) e um limite: count (2 a 730 ocorrências) ou until (AAAA-MM-DD). Sem limite, gera o máximo da frequência. |
reminders | array de objeto | Não | Lembretes (até 10), com os campos de lembretes. Numa série, cada ocorrência recebe os seus. |
sync_google | boolean | Não | Cria também no Google Agenda do usuário API (se conectado). |
sync_microsoft | boolean | Não | Cria também no Outlook do usuário API (se conectado). |
create_teams_meeting | boolean | Não | Com sync_microsoft, gera a reunião do Teams (conta de trabalho). |
Exemplos de código — criar evento
curl -X POST "https://api.atys.pro/api/v1/calendar/events" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"title": "Reunião de proposta",
"type_id": 1,
"description": "Apresentar a proposta comercial.",
"start_at": "2026-12-01T10:00:00-03:00",
"end_at": "2026-12-01T11:00:00-03:00",
"user_ids": [77, 81],
"contact_ids": [5120],
"reminders": [
{
"amount": 30,
"unit": "minutes",
"notify_contacts": true,
"channel_id": 44
}
],
"sync_google": true
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/events', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"title": "Reunião de proposta",
"type_id": 1,
"description": "Apresentar a proposta comercial.",
"start_at": "2026-12-01T10:00:00-03:00",
"end_at": "2026-12-01T11:00:00-03:00",
"user_ids": [77, 81],
"contact_ids": [5120],
"reminders": [
{
"amount": 30,
"unit": "minutes",
"notify_contacts": true,
"channel_id": 44
}
],
"sync_google": true
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.post(
'https://api.atys.pro/api/v1/calendar/events',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'title': 'Reunião de proposta',
'type_id': 1,
'description': 'Apresentar a proposta comercial.',
'start_at': '2026-12-01T10:00:00-03:00',
'end_at': '2026-12-01T11:00:00-03:00',
'user_ids': [77, 81],
'contact_ids': [5120],
'reminders': [
{
'amount': 30,
'unit': 'minutes',
'notify_contacts': True,
'channel_id': 44
}
],
'sync_google': True
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'title' => 'Reunião de proposta',
'type_id' => 1,
'description' => 'Apresentar a proposta comercial.',
'start_at' => '2026-12-01T10:00:00-03:00',
'end_at' => '2026-12-01T11:00:00-03:00',
'user_ids' => [77, 81],
'contact_ids' => [5120],
'reminders' => [
[
'amount' => 30,
'unit' => 'minutes',
'notify_contacts' => true,
'channel_id' => 44
]
],
'sync_google' => true
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('POST', 'v1/calendar/events', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'title' => 'Reunião de proposta',
'type_id' => 1,
'description' => 'Apresentar a proposta comercial.',
'start_at' => '2026-12-01T10:00:00-03:00',
'end_at' => '2026-12-01T11:00:00-03:00',
'user_ids' => [77, 81],
'contact_ids' => [5120],
'reminders' => [
[
'amount' => 30,
'unit' => 'minutes',
'notify_contacts' => true,
'channel_id' => 44
]
],
'sync_google' => true
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"title": "Reunião de proposta",
"type_id": 1,
"description": "Apresentar a proposta comercial.",
"start_at": "2026-12-01T10:00:00-03:00",
"end_at": "2026-12-01T11:00:00-03:00",
"user_ids": [77, 81],
"contact_ids": [5120],
"reminders": [
{
"amount": 30,
"unit": "minutes",
"notify_contacts": true,
"channel_id": 44
}
],
"sync_google": true
}`)
req, _ := http.NewRequest("POST", "https://api.atys.pro/api/v1/calendar/events", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"id": 4210,
"title": "Reunião de proposta",
"description": "Apresentar a proposta comercial.",
"color": "#1976d2",
"type": {
"id": 1,
"name": "MEETING"
},
"calendar_id": 12,
"start_at": "2026-12-01T10:00:00-03:00",
"end_at": "2026-12-01T11:00:00-03:00",
"time_zone": "America/Sao_Paulo",
"reminder_message": null,
"origin": "system",
"created_by": 90,
"series": null,
"users": [
{
"id": 77,
"name": "Carlos Vendedor",
"invitation_status": "accepted",
"responded_at": "2026-11-04T16:20:00-03:00"
},
{
"id": 81,
"name": "Ana Consultora",
"invitation_status": "pending",
"responded_at": null
}
],
"contacts": [
{
"id": 5120,
"name": "Maria Cliente"
}
],
"synced": {
"google": true,
"microsoft": false
},
"created_at": "2026-11-04T16:02:11-03:00",
"updated_at": "2026-11-04T16:02:11-03:00"
},
"conflicts": [
{
"source": "atys",
"event_id": 4188,
"title": "Visita técnica",
"user": {
"id": 81,
"name": "Ana Consultora"
},
"start_at": "2026-12-01T10:30:00-03:00",
"end_at": "2026-12-01T11:30:00-03:00"
}
]
}
Para uma série, envie recurrence; a resposta é a primeira ocorrência:
Exemplos de código — criar evento recorrente
curl -X POST "https://api.atys.pro/api/v1/calendar/events" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"title": "Aula semanal",
"type_id": 9,
"start_at": "2026-12-07T09:00:00-03:00",
"end_at": "2026-12-07T10:00:00-03:00",
"user_ids": [77],
"recurrence": {
"frequency": "weekly",
"count": 4
}
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/events', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"title": "Aula semanal",
"type_id": 9,
"start_at": "2026-12-07T09:00:00-03:00",
"end_at": "2026-12-07T10:00:00-03:00",
"user_ids": [77],
"recurrence": {
"frequency": "weekly",
"count": 4
}
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.post(
'https://api.atys.pro/api/v1/calendar/events',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'title': 'Aula semanal',
'type_id': 9,
'start_at': '2026-12-07T09:00:00-03:00',
'end_at': '2026-12-07T10:00:00-03:00',
'user_ids': [77],
'recurrence': {
'frequency': 'weekly',
'count': 4
}
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'title' => 'Aula semanal',
'type_id' => 9,
'start_at' => '2026-12-07T09:00:00-03:00',
'end_at' => '2026-12-07T10:00:00-03:00',
'user_ids' => [77],
'recurrence' => [
'frequency' => 'weekly',
'count' => 4
]
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('POST', 'v1/calendar/events', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'title' => 'Aula semanal',
'type_id' => 9,
'start_at' => '2026-12-07T09:00:00-03:00',
'end_at' => '2026-12-07T10:00:00-03:00',
'user_ids' => [77],
'recurrence' => [
'frequency' => 'weekly',
'count' => 4
]
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"title": "Aula semanal",
"type_id": 9,
"start_at": "2026-12-07T09:00:00-03:00",
"end_at": "2026-12-07T10:00:00-03:00",
"user_ids": [77],
"recurrence": {
"frequency": "weekly",
"count": 4
}
}`)
req, _ := http.NewRequest("POST", "https://api.atys.pro/api/v1/calendar/events", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"id": 4300,
"title": "Aula semanal",
"description": "Apresentar a proposta comercial.",
"color": "#1976d2",
"type": {
"id": 1,
"name": "MEETING"
},
"calendar_id": 12,
"start_at": "2026-12-07T09:00:00-03:00",
"end_at": "2026-12-07T10:00:00-03:00",
"time_zone": "America/Sao_Paulo",
"reminder_message": null,
"origin": "system",
"created_by": 90,
"series": {
"id": 4300,
"occurrence": 1,
"recurrence": {
"frequency": "weekly",
"interval": 1,
"count": 4,
"until": null,
"occurrences": 4
}
},
"users": [
{
"id": 77,
"name": "Carlos Vendedor",
"invitation_status": "accepted",
"responded_at": "2026-11-04T16:20:00-03:00"
},
{
"id": 81,
"name": "Ana Consultora",
"invitation_status": "pending",
"responded_at": null
}
],
"contacts": [
{
"id": 5120,
"name": "Maria Cliente"
}
],
"synced": {
"google": true,
"microsoft": false
},
"created_at": "2026-11-04T16:02:11-03:00",
"updated_at": "2026-11-04T16:02:11-03:00"
},
"conflicts": []
}
Editar evento
Envie só o que muda; os mesmos campos de criar, exceto calendar_id.
user_ids, contact_ids e reminders, quando enviados, substituem a lista
inteira. Quem já estava convidado mantém a resposta ao convite; quem entrou agora recebe o convite, e mudar data
ou hora avisa os demais participantes. Mudou o horário e não enviou reminders? Os lembretes atuais
são reagendados para o novo horário. O que já está no Google ou no Outlook é atualizado lá.
Editar exige ser o criador do evento ou administrador da empresa (evento sem criador: qualquer participante).
scope | Em uma série, altera | Limitações |
|---|---|---|
this (default) | Só esta ocorrência. | Pode mudar data e hora. Num evento avulso, recurrence o transforma em série. |
following | Esta e as próximas. | Não muda data nem hora (series_schedule_not_supported). "recurrence": null encerra a série: as ocorrências depois desta são excluídas. |
all | Todas as ocorrências. | Muda a hora em todas, não a data: start_at/end_at precisam manter o dia desta ocorrência (series_date_change_not_supported). |
A regra de repetição de uma série existente não muda (series_recurrence_immutable): encerre a série
e crie outra. Contato vinculado na edição precisa ter canal (telefone ou e-mail) na Atys
(contact_without_channel).
Exemplos de código — editar evento
curl -X PATCH "https://api.atys.pro/api/v1/calendar/events/4210" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"title": "Reunião de proposta (revisada)",
"start_at": "2026-12-01T14:00:00-03:00",
"end_at": "2026-12-01T15:00:00-03:00"
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"title": "Reunião de proposta (revisada)",
"start_at": "2026-12-01T14:00:00-03:00",
"end_at": "2026-12-01T15:00:00-03:00"
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.patch(
'https://api.atys.pro/api/v1/calendar/events/4210',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'title': 'Reunião de proposta (revisada)',
'start_at': '2026-12-01T14:00:00-03:00',
'end_at': '2026-12-01T15:00:00-03:00'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'title' => 'Reunião de proposta (revisada)',
'start_at' => '2026-12-01T14:00:00-03:00',
'end_at' => '2026-12-01T15:00:00-03:00'
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('PATCH', 'v1/calendar/events/4210', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'title' => 'Reunião de proposta (revisada)',
'start_at' => '2026-12-01T14:00:00-03:00',
'end_at' => '2026-12-01T15:00:00-03:00'
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"title": "Reunião de proposta (revisada)",
"start_at": "2026-12-01T14:00:00-03:00",
"end_at": "2026-12-01T15:00:00-03:00"
}`)
req, _ := http.NewRequest("PATCH", "https://api.atys.pro/api/v1/calendar/events/4210", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"id": 4210,
"title": "Reunião de proposta (revisada)",
"description": "Apresentar a proposta comercial.",
"color": "#1976d2",
"type": {
"id": 1,
"name": "MEETING"
},
"calendar_id": 12,
"start_at": "2026-12-01T14:00:00-03:00",
"end_at": "2026-12-01T15:00:00-03:00",
"time_zone": "America/Sao_Paulo",
"reminder_message": null,
"origin": "system",
"created_by": 90,
"series": null,
"users": [
{
"id": 77,
"name": "Carlos Vendedor",
"invitation_status": "accepted",
"responded_at": "2026-11-04T16:20:00-03:00"
},
{
"id": 81,
"name": "Ana Consultora",
"invitation_status": "pending",
"responded_at": null
}
],
"contacts": [
{
"id": 5120,
"name": "Maria Cliente"
}
],
"synced": {
"google": true,
"microsoft": false
},
"created_at": "2026-11-04T16:02:11-03:00",
"updated_at": "2026-11-04T16:02:11-03:00"
},
"conflicts": []
}
Exemplos de código — editar todas as ocorrências da série
curl -X PATCH "https://api.atys.pro/api/v1/calendar/events/4301" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"scope": "all",
"title": "Aula semanal (sala 2)",
"start_at": "2026-12-14T09:30:00-03:00",
"end_at": "2026-12-14T10:30:00-03:00"
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4301', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"scope": "all",
"title": "Aula semanal (sala 2)",
"start_at": "2026-12-14T09:30:00-03:00",
"end_at": "2026-12-14T10:30:00-03:00"
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.patch(
'https://api.atys.pro/api/v1/calendar/events/4301',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'scope': 'all',
'title': 'Aula semanal (sala 2)',
'start_at': '2026-12-14T09:30:00-03:00',
'end_at': '2026-12-14T10:30:00-03:00'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4301');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'scope' => 'all',
'title' => 'Aula semanal (sala 2)',
'start_at' => '2026-12-14T09:30:00-03:00',
'end_at' => '2026-12-14T10:30:00-03:00'
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('PATCH', 'v1/calendar/events/4301', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'scope' => 'all',
'title' => 'Aula semanal (sala 2)',
'start_at' => '2026-12-14T09:30:00-03:00',
'end_at' => '2026-12-14T10:30:00-03:00'
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"scope": "all",
"title": "Aula semanal (sala 2)",
"start_at": "2026-12-14T09:30:00-03:00",
"end_at": "2026-12-14T10:30:00-03:00"
}`)
req, _ := http.NewRequest("PATCH", "https://api.atys.pro/api/v1/calendar/events/4301", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"id": 4301,
"title": "Aula semanal (sala 2)",
"description": "Apresentar a proposta comercial.",
"color": "#1976d2",
"type": {
"id": 1,
"name": "MEETING"
},
"calendar_id": 12,
"start_at": "2026-12-14T09:30:00-03:00",
"end_at": "2026-12-14T10:30:00-03:00",
"time_zone": "America/Sao_Paulo",
"reminder_message": null,
"origin": "system",
"created_by": 90,
"series": {
"id": 4300,
"occurrence": 2,
"recurrence": {
"frequency": "weekly",
"interval": 1,
"count": 4,
"until": null,
"occurrences": 4
}
},
"users": [
{
"id": 77,
"name": "Carlos Vendedor",
"invitation_status": "accepted",
"responded_at": "2026-11-04T16:20:00-03:00"
},
{
"id": 81,
"name": "Ana Consultora",
"invitation_status": "pending",
"responded_at": null
}
],
"contacts": [
{
"id": 5120,
"name": "Maria Cliente"
}
],
"synced": {
"google": true,
"microsoft": false
},
"created_at": "2026-11-04T16:02:11-03:00",
"updated_at": "2026-11-04T16:02:11-03:00"
},
"conflicts": []
}
Série do evento
Situação da série a que a ocorrência pertence: posição (occurrence), total, quantas vêm depois
(following), a regra de repetição e todas as ocorrências. Evento avulso responde
"is_series": false.
Exemplos de código — série do evento
curl "https://api.atys.pro/api/v1/calendar/events/4301/series" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4301/series', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/events/4301/series',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4301/series');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/events/4301/series', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/events/4301/series", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"is_series": true,
"series_id": 4300,
"occurrence": 2,
"total": 4,
"following": 2,
"recurrence": {
"frequency": "weekly",
"interval": 1,
"count": 4,
"until": null,
"occurrences": 4
},
"occurrences": [
{
"id": 4300,
"occurrence": 1,
"start_at": "2026-12-07T09:00:00-03:00",
"end_at": "2026-12-07T10:00:00-03:00"
},
{
"id": 4301,
"occurrence": 2,
"start_at": "2026-12-14T09:00:00-03:00",
"end_at": "2026-12-14T10:00:00-03:00"
},
{
"id": 4302,
"occurrence": 3,
"start_at": "2026-12-21T09:00:00-03:00",
"end_at": "2026-12-21T10:00:00-03:00"
},
{
"id": 4303,
"occurrence": 4,
"start_at": "2026-12-28T09:00:00-03:00",
"end_at": "2026-12-28T10:00:00-03:00"
}
]
}
}
Verificar conflitos
Antes de marcar, confira se os usuários já têm algo no horário — o mesmo aviso que a tela mostra ao montar o
evento. Não grava nada. source diz de onde veio o choque: atys (evento da Agenda, com
event_id), google ou microsoft (horário ocupado na agenda externa do
usuário API, sem detalhes).
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
user_ids | array de integer | Sim | Usuários a verificar (1 a 50). |
start_at, end_at | data ISO 8601 | Sim | Intervalo pretendido. |
ignore_event_id | integer | Não | Evento a desconsiderar (ao remarcar, o próprio). |
include_google, include_microsoft | boolean | Não | Consultar também o Google Agenda / Outlook do usuário API. |
Exemplos de código — verificar conflitos
curl -X POST "https://api.atys.pro/api/v1/calendar/events/check-conflicts" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"user_ids": [77, 81],
"start_at": "2026-12-01T10:00:00-03:00",
"end_at": "2026-12-01T11:00:00-03:00"
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/check-conflicts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"user_ids": [77, 81],
"start_at": "2026-12-01T10:00:00-03:00",
"end_at": "2026-12-01T11:00:00-03:00"
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.post(
'https://api.atys.pro/api/v1/calendar/events/check-conflicts',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'user_ids': [77, 81],
'start_at': '2026-12-01T10:00:00-03:00',
'end_at': '2026-12-01T11:00:00-03:00'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/check-conflicts');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'user_ids' => [77, 81],
'start_at' => '2026-12-01T10:00:00-03:00',
'end_at' => '2026-12-01T11:00:00-03:00'
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('POST', 'v1/calendar/events/check-conflicts', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'user_ids' => [77, 81],
'start_at' => '2026-12-01T10:00:00-03:00',
'end_at' => '2026-12-01T11:00:00-03:00'
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"user_ids": [77, 81],
"start_at": "2026-12-01T10:00:00-03:00",
"end_at": "2026-12-01T11:00:00-03:00"
}`)
req, _ := http.NewRequest("POST", "https://api.atys.pro/api/v1/calendar/events/check-conflicts", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": [
{
"source": "atys",
"event_id": 4188,
"title": "Visita técnica",
"user": {
"id": 81,
"name": "Ana Consultora"
},
"start_at": "2026-12-01T10:30:00-03:00",
"end_at": "2026-12-01T11:30:00-03:00"
}
]
}
Excluir evento
Exclui o evento e avisa os participantes do cancelamento; o que estava no Google Agenda ou no Outlook é removido
lá. Numa série, scope escolhe o alcance: this (default, só esta ocorrência),
following (esta e as próximas) ou all (a série inteira). Exige a permissão
Excluir eventos e ser o criador ou administrador. A exclusão é definitiva.
Exemplos de código — excluir evento
curl -X DELETE "https://api.atys.pro/api/v1/calendar/events/4210" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
console.log(response.status); // 204 = excluído
import os
import requests
response = requests.delete(
'https://api.atys.pro/api/v1/calendar/events/4210',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
print(response.status_code) # 204 = excluído
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('DELETE', 'v1/calendar/events/4210', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.atys.pro/api/v1/calendar/events/4210", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
Exemplos de código — excluir esta e as próximas ocorrências
curl -X DELETE "https://api.atys.pro/api/v1/calendar/events/4302?scope=following" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4302?scope=following', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
console.log(response.status); // 204 = excluído
import os
import requests
response = requests.delete(
'https://api.atys.pro/api/v1/calendar/events/4302?scope=following',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
print(response.status_code) # 204 = excluído
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4302?scope=following');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('DELETE', 'v1/calendar/events/4302', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'query' => [
'scope' => 'following'
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.atys.pro/api/v1/calendar/events/4302?scope=following", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
Importar eventos
Cria até 100 eventos por chamada, cada um pela mesma rotina de criar evento (mesmos
campos, convites, lembretes e sincronização). Cada item é independente: um item inválido não impede os outros
e não deixa nada gravado. O resultado vem na ordem enviada, com o id criado ou o erro do item.
Exemplos de código — importar eventos
curl -X POST "https://api.atys.pro/api/v1/calendar/events/import" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"title": "Consulta — Maria",
"type_id": 5,
"start_at": "2026-12-02T09:00:00-03:00",
"end_at": "2026-12-02T09:30:00-03:00",
"user_ids": [77],
"contact_ids": [5120]
},
{
"title": "Consulta — João",
"type_id": 5,
"start_at": "2026-12-02T10:00:00-03:00",
"end_at": "2026-12-02T10:30:00-03:00",
"user_ids": [999]
}
]
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/import', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"events": [
{
"title": "Consulta — Maria",
"type_id": 5,
"start_at": "2026-12-02T09:00:00-03:00",
"end_at": "2026-12-02T09:30:00-03:00",
"user_ids": [77],
"contact_ids": [5120]
},
{
"title": "Consulta — João",
"type_id": 5,
"start_at": "2026-12-02T10:00:00-03:00",
"end_at": "2026-12-02T10:30:00-03:00",
"user_ids": [999]
}
]
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.post(
'https://api.atys.pro/api/v1/calendar/events/import',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'events': [
{
'title': 'Consulta — Maria',
'type_id': 5,
'start_at': '2026-12-02T09:00:00-03:00',
'end_at': '2026-12-02T09:30:00-03:00',
'user_ids': [77],
'contact_ids': [5120]
},
{
'title': 'Consulta — João',
'type_id': 5,
'start_at': '2026-12-02T10:00:00-03:00',
'end_at': '2026-12-02T10:30:00-03:00',
'user_ids': [999]
}
]
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/import');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'events' => [
[
'title' => 'Consulta — Maria',
'type_id' => 5,
'start_at' => '2026-12-02T09:00:00-03:00',
'end_at' => '2026-12-02T09:30:00-03:00',
'user_ids' => [77],
'contact_ids' => [5120]
],
[
'title' => 'Consulta — João',
'type_id' => 5,
'start_at' => '2026-12-02T10:00:00-03:00',
'end_at' => '2026-12-02T10:30:00-03:00',
'user_ids' => [999]
]
]
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('POST', 'v1/calendar/events/import', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'events' => [
[
'title' => 'Consulta — Maria',
'type_id' => 5,
'start_at' => '2026-12-02T09:00:00-03:00',
'end_at' => '2026-12-02T09:30:00-03:00',
'user_ids' => [77],
'contact_ids' => [5120]
],
[
'title' => 'Consulta — João',
'type_id' => 5,
'start_at' => '2026-12-02T10:00:00-03:00',
'end_at' => '2026-12-02T10:30:00-03:00',
'user_ids' => [999]
]
]
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"events": [
{
"title": "Consulta — Maria",
"type_id": 5,
"start_at": "2026-12-02T09:00:00-03:00",
"end_at": "2026-12-02T09:30:00-03:00",
"user_ids": [77],
"contact_ids": [5120]
},
{
"title": "Consulta — João",
"type_id": 5,
"start_at": "2026-12-02T10:00:00-03:00",
"end_at": "2026-12-02T10:30:00-03:00",
"user_ids": [999]
}
]
}`)
req, _ := http.NewRequest("POST", "https://api.atys.pro/api/v1/calendar/events/import", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": [
{
"index": 0,
"id": 4400
},
{
"index": 1,
"error": {
"code": "invalid_user",
"message": "Usuário não encontrado na empresa."
}
}
],
"meta": {
"total": 2,
"created": 1,
"failed": 1
}
}
Participantes
Usuários (com a resposta ao convite: pending, accepted ou declined) e
contatos do evento. O PUT substitui a lista enviada (user_ids e/ou
contact_ids); a que não vier fica como está. Aceita scope como em
editar. Quem entra recebe o convite.
Exemplos de código — listar participantes
curl "https://api.atys.pro/api/v1/calendar/events/4210/participants" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210/participants', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/events/4210/participants',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210/participants');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/events/4210/participants', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/events/4210/participants", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"users": [
{
"id": 77,
"name": "Carlos Vendedor",
"invitation_status": "accepted",
"responded_at": "2026-11-04T16:20:00-03:00"
},
{
"id": 81,
"name": "Ana Consultora",
"invitation_status": "pending",
"responded_at": null
}
],
"contacts": [
{
"id": 5120,
"name": "Maria Cliente"
}
]
}
}
Exemplos de código — substituir participantes
curl -X PUT "https://api.atys.pro/api/v1/calendar/events/4210/participants" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"user_ids": [77],
"contact_ids": [5120]
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210/participants', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"user_ids": [77],
"contact_ids": [5120]
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.put(
'https://api.atys.pro/api/v1/calendar/events/4210/participants',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'user_ids': [77],
'contact_ids': [5120]
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210/participants');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'user_ids' => [77],
'contact_ids' => [5120]
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('PUT', 'v1/calendar/events/4210/participants', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'user_ids' => [77],
'contact_ids' => [5120]
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"user_ids": [77],
"contact_ids": [5120]
}`)
req, _ := http.NewRequest("PUT", "https://api.atys.pro/api/v1/calendar/events/4210/participants", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"users": [
{
"id": 77,
"name": "Carlos Vendedor",
"invitation_status": "accepted",
"responded_at": "2026-11-04T16:20:00-03:00"
}
],
"contacts": [
{
"id": 5120,
"name": "Maria Cliente"
}
]
}
}
Responder ao convite
Aceita ou recusa o convite do próprio usuário API — ninguém responde por outro usuário. É a
mesma ação dos botões do e-mail de convite: o organizador é avisado (e, na recusa, recebe e-mail) e a resposta
vai para o Google Agenda/Outlook. Usuário API que não participa do evento recebe not_a_participant.
Exemplos de código — responder ao convite
curl -X POST "https://api.atys.pro/api/v1/calendar/events/4210/invitation-response" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"status": "accepted"
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210/invitation-response', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"status": "accepted"
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.post(
'https://api.atys.pro/api/v1/calendar/events/4210/invitation-response',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'status': 'accepted'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210/invitation-response');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'status' => 'accepted'
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('POST', 'v1/calendar/events/4210/invitation-response', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'status' => 'accepted'
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"status": "accepted"
}`)
req, _ := http.NewRequest("POST", "https://api.atys.pro/api/v1/calendar/events/4210/invitation-response", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"users": [
{
"id": 77,
"name": "Carlos Vendedor",
"invitation_status": "accepted",
"responded_at": "2026-11-04T16:20:00-03:00"
},
{
"id": 81,
"name": "Ana Consultora",
"invitation_status": "pending",
"responded_at": null
}
],
"contacts": [
{
"id": 5120,
"name": "Maria Cliente"
}
]
}
}
Lembretes
Avisos disparados antes do evento. Os atendentes sempre recebem o aviso no sistema e por e-mail; com
notify_contacts, os contatos também. O horário do disparo (scheduled_at) é calculado
a partir do início do evento e recalculado quando o evento muda de horário. Numa série, cada ocorrência tem os
seus lembretes: os endpoints abaixo alteram só a ocorrência do {id}.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
amount | integer | Sim | Antecedência. |
unit | string | Sim | minutes, hours, days ou weeks. |
type | string | Não | notification (default; WhatsApp pelo canal) ou email (e-mail transacional da empresa). |
notify_contacts | boolean | Não | Avisar também os contatos do evento. |
send_whatsapp_to_staff | boolean | Não | Com notification, mandar WhatsApp também aos atendentes. |
channel_id | integer | Com WhatsApp | Canal de WhatsApp da empresa usado no envio (invalid_channel). |
waba_template | objeto | Canal oficial | Template aprovado da API oficial, usado quando a janela de 24 h está fechada. |
status: scheduled, processing, sent ou failed;
messages lista o que foi gerado no disparo. Só lembretes scheduled podem ser editados
(reminder_not_scheduled). O texto enviado aos contatos é o reminder_message do evento.
Exemplos de código — listar lembretes
curl "https://api.atys.pro/api/v1/calendar/events/4210/reminders" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210/reminders', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/events/4210/reminders',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210/reminders');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/events/4210/reminders', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/events/4210/reminders", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": [
{
"id": 9031,
"event_id": 4210,
"type": "notification",
"amount": 30,
"unit": "minutes",
"notify_contacts": true,
"send_whatsapp_to_staff": false,
"channel_id": 44,
"waba_template": null,
"scheduled_at": "2026-12-01T09:30:00-03:00",
"status": "scheduled",
"messages": [],
"created_at": "2026-11-04T16:02:11-03:00",
"updated_at": "2026-11-04T16:02:11-03:00"
}
]
}
Exemplos de código — criar lembrete
curl -X POST "https://api.atys.pro/api/v1/calendar/events/4210/reminders" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"amount": 30,
"unit": "minutes",
"notify_contacts": true,
"channel_id": 44
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210/reminders', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"amount": 30,
"unit": "minutes",
"notify_contacts": true,
"channel_id": 44
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.post(
'https://api.atys.pro/api/v1/calendar/events/4210/reminders',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'amount': 30,
'unit': 'minutes',
'notify_contacts': True,
'channel_id': 44
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210/reminders');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'amount' => 30,
'unit' => 'minutes',
'notify_contacts' => true,
'channel_id' => 44
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('POST', 'v1/calendar/events/4210/reminders', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'amount' => 30,
'unit' => 'minutes',
'notify_contacts' => true,
'channel_id' => 44
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"amount": 30,
"unit": "minutes",
"notify_contacts": true,
"channel_id": 44
}`)
req, _ := http.NewRequest("POST", "https://api.atys.pro/api/v1/calendar/events/4210/reminders", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"id": 9031,
"event_id": 4210,
"type": "notification",
"amount": 30,
"unit": "minutes",
"notify_contacts": true,
"send_whatsapp_to_staff": false,
"channel_id": 44,
"waba_template": null,
"scheduled_at": "2026-12-01T09:30:00-03:00",
"status": "scheduled",
"messages": [],
"created_at": "2026-11-04T16:02:11-03:00",
"updated_at": "2026-11-04T16:02:11-03:00"
}
}
Exemplos de código — editar lembrete
curl -X PATCH "https://api.atys.pro/api/v1/calendar/events/4210/reminders/9031" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"amount": 1,
"unit": "days"
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210/reminders/9031', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"amount": 1,
"unit": "days"
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.patch(
'https://api.atys.pro/api/v1/calendar/events/4210/reminders/9031',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'amount': 1,
'unit': 'days'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210/reminders/9031');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'amount' => 1,
'unit' => 'days'
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('PATCH', 'v1/calendar/events/4210/reminders/9031', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'amount' => 1,
'unit' => 'days'
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"amount": 1,
"unit": "days"
}`)
req, _ := http.NewRequest("PATCH", "https://api.atys.pro/api/v1/calendar/events/4210/reminders/9031", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"id": 9031,
"event_id": 4210,
"type": "notification",
"amount": 1,
"unit": "days",
"notify_contacts": true,
"send_whatsapp_to_staff": false,
"channel_id": 44,
"waba_template": null,
"scheduled_at": "2026-11-30T10:00:00-03:00",
"status": "scheduled",
"messages": [],
"created_at": "2026-11-04T16:02:11-03:00",
"updated_at": "2026-11-04T16:02:11-03:00"
}
}
Exemplos de código — excluir lembrete
curl -X DELETE "https://api.atys.pro/api/v1/calendar/events/4210/reminders/9031" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210/reminders/9031', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
console.log(response.status); // 204 = excluído
import os
import requests
response = requests.delete(
'https://api.atys.pro/api/v1/calendar/events/4210/reminders/9031',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
print(response.status_code) # 204 = excluído
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210/reminders/9031');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('DELETE', 'v1/calendar/events/4210/reminders/9031', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.atys.pro/api/v1/calendar/events/4210/reminders/9031", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
Para mudar a mensagem enviada aos contatos, edite o evento:
Exemplos de código — mensagem personalizada dos lembretes
curl -X PATCH "https://api.atys.pro/api/v1/calendar/events/4210" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"reminder_message": "Olá! Lembrete: amanhã temos a reunião de proposta."
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"reminder_message": "Olá! Lembrete: amanhã temos a reunião de proposta."
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.patch(
'https://api.atys.pro/api/v1/calendar/events/4210',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'reminder_message': 'Olá! Lembrete: amanhã temos a reunião de proposta.'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'reminder_message' => 'Olá! Lembrete: amanhã temos a reunião de proposta.'
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('PATCH', 'v1/calendar/events/4210', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'reminder_message' => 'Olá! Lembrete: amanhã temos a reunião de proposta.'
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"reminder_message": "Olá! Lembrete: amanhã temos a reunião de proposta."
}`)
req, _ := http.NewRequest("PATCH", "https://api.atys.pro/api/v1/calendar/events/4210", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"id": 4210,
"title": "Reunião de proposta",
"description": "Apresentar a proposta comercial.",
"color": "#1976d2",
"type": {
"id": 1,
"name": "MEETING"
},
"calendar_id": 12,
"start_at": "2026-12-01T10:00:00-03:00",
"end_at": "2026-12-01T11:00:00-03:00",
"time_zone": "America/Sao_Paulo",
"reminder_message": "Olá! Lembrete: amanhã temos a reunião de proposta.",
"origin": "system",
"created_by": 90,
"series": null,
"users": [
{
"id": 77,
"name": "Carlos Vendedor",
"invitation_status": "accepted",
"responded_at": "2026-11-04T16:20:00-03:00"
},
{
"id": 81,
"name": "Ana Consultora",
"invitation_status": "pending",
"responded_at": null
}
],
"contacts": [
{
"id": 5120,
"name": "Maria Cliente"
}
],
"synced": {
"google": true,
"microsoft": false
},
"created_at": "2026-11-04T16:02:11-03:00",
"updated_at": "2026-11-04T16:02:11-03:00"
},
"conflicts": []
}
Anexos
Arquivos do evento (pauta, contrato…), enviados um por chamada no campo file em
multipart/form-data. Mesmo limite da plataforma: até 5 arquivos e 50 MB no total por evento
(too_many_files, files_too_large). Os arquivos vão para o armazenamento da empresa
(Google Drive, se conectado) e seguem junto no último lembrete enviado aos contatos. Numa série, o anexo
enviado pela API fica só na ocorrência do {id}.
Exemplos de código — anexar arquivo ao evento
curl -X POST "https://api.atys.pro/api/v1/calendar/events/4210/files" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-F "file=@pauta.pdf"
const form = new FormData();
form.append('file', fileInput.files[0]); // ou new Blob([...]), 'pauta.pdf'
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210/files', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
},
body: form // não defina Content-Type: o navegador/Node põe o boundary
});
const { data, error } = await response.json();
import os
import requests
with open('pauta.pdf', 'rb') as f:
response = requests.post(
'https://api.atys.pro/api/v1/calendar/events/4210/files',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
files={'file': f}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210/files');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('pauta.pdf'),
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('POST', 'v1/calendar/events/4210/files', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'multipart' => [
['name' => 'file', 'contents' => fopen('pauta.pdf', 'r'), 'filename' => 'pauta.pdf'],
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
var body bytes.Buffer
form := multipart.NewWriter(&body)
part, _ := form.CreateFormFile("file", "pauta.pdf")
file, _ := os.Open("pauta.pdf")
defer file.Close()
io.Copy(part, file)
form.Close()
req, _ := http.NewRequest("POST", "https://api.atys.pro/api/v1/calendar/events/4210/files", &body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", form.FormDataContentType())
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"id": 655,
"name": "pauta.pdf",
"mime_type": "application/pdf",
"size": 20480,
"url": "https://files.atys.pro/storage/files/company-310/files-calendar/pauta.pdf",
"created_at": "2026-11-04T16:10:00-03:00"
}
}
Exemplos de código — listar anexos
curl "https://api.atys.pro/api/v1/calendar/events/4210/files" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210/files', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/events/4210/files',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210/files');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/events/4210/files', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/events/4210/files", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": [
{
"id": 655,
"name": "pauta.pdf",
"mime_type": "application/pdf",
"size": 20480,
"url": "https://files.atys.pro/storage/files/company-310/files-calendar/pauta.pdf",
"created_at": "2026-11-04T16:10:00-03:00"
}
]
}
Exemplos de código — remover anexo
curl -X DELETE "https://api.atys.pro/api/v1/calendar/events/4210/files/655" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/events/4210/files/655', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
console.log(response.status); // 204 = excluído
import os
import requests
response = requests.delete(
'https://api.atys.pro/api/v1/calendar/events/4210/files/655',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
print(response.status_code) # 204 = excluído
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/events/4210/files/655');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('DELETE', 'v1/calendar/events/4210/files/655', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.atys.pro/api/v1/calendar/events/4210/files/655", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
Horário de atendimento
É a agenda pública de um usuário — a mesma tela Meu horário disponível /
Configurar agenda pública de Colaboradores: em que dias e faixas ele aceita reservas, a
duração de cada horário, até quando se pode reservar, os dias de exceção, os tipos de evento oferecidos e
os lembretes. É dela que saem os horários livres e as
reservas. As faixas são no fuso da empresa (timezone).
Exemplos de código — consultar horário
curl "https://api.atys.pro/api/v1/calendar/users/77/working-hours" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/users/77/working-hours', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/users/77/working-hours',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/users/77/working-hours');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/users/77/working-hours', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/users/77/working-hours", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"user_id": 77,
"active": true,
"timezone": "America/Sao_Paulo",
"slot_duration": 30,
"min_notice_minutes": 10,
"horizon": {
"unit": "months",
"amount": 2
},
"weekly": {
"monday": [
"09:00-12:00",
"14:00-18:00"
],
"tuesday": [
"09:00-12:00",
"14:00-18:00"
],
"wednesday": [
"09:00-12:00"
],
"thursday": [
"09:00-12:00",
"14:00-18:00"
],
"friday": [
"09:00-12:00"
],
"saturday": [],
"sunday": []
},
"exceptions": [
{
"date": "2026-12-24",
"type": "closed",
"intervals": []
},
{
"date": "2026-12-30",
"type": "replace",
"intervals": [
"09:00-11:00"
]
}
],
"event_types": [
{
"id": 1,
"name": "Reunião",
"duration": null,
"effective_duration": 30,
"default": true
},
{
"id": 5,
"name": "Consulta",
"duration": 60,
"effective_duration": 60,
"default": false
}
],
"notifications": [
{
"amount": 1,
"unit": "days",
"type": "email",
"notify_contacts": true,
"send_whatsapp_to_staff": false,
"company_channel_id": null,
"meta_waba_id": null,
"waba_template": null
}
]
}
}
| Campo | Tipo | Descrição |
|---|---|---|
active | boolean | Agenda pública ligada. Desligada, não há horários livres nem reservas (scheduling_inactive). Para ligar, é preciso ao menos um dia com faixa, slot_duration e horizon. |
slot_duration | integer | Duração de cada horário, em minutos (5 a 480). Também é o passo da grade: 30 gera 09:00, 09:30, 10:00… |
horizon | objeto | Até quando se pode reservar: unit days (até 365) ou months (até 12) e amount. |
weekly | objeto | Faixas por dia (monday … sunday), cada uma HH:MM-HH:MM, sem sobreposição. Dia ausente ou [] = sem atendimento. |
exceptions | array | Datas (AAAA-MM-DD, de hoje até o fim do horizon) com type closed (fechado) ou replace (troca as faixas do dia por intervals). Datas passadas somem sozinhas. |
event_types | array | Tipos de evento que o contato pode escolher: id (tipo da agenda, menos Lembrete e Mensagem), duration própria opcional (null segue slot_duration) e um default. |
notifications | array | Até 10 lembretes de cada reserva: amount + unit (minutes, hours, days, weeks) antes, type notification ou email, notify_contacts, send_whatsapp_to_staff e o canal (company_channel_id, meta_waba_id, waba_template). |
min_notice_minutes | integer | Antecedência mínima para reservar (só leitura). |
No PUT envie só o que muda: o resto fica como está. weekly, exceptions,
event_types e notifications, quando enviados, substituem a lista inteira. A
validação é a da plataforma; os erros vêm em details com os nomes acima
(weekly.monday, exceptions.0.date…). Canal de outra empresa devolve
invalid_company_channel. A resposta é o horário completo, como no GET.
Exemplos de código — definir horário
curl -X PUT "https://api.atys.pro/api/v1/calendar/users/77/working-hours" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"active": true,
"slot_duration": 30,
"horizon": {
"unit": "months",
"amount": 2
},
"weekly": {
"monday": ["09:00-12:00", "14:00-18:00"],
"tuesday": ["09:00-12:00", "14:00-18:00"],
"wednesday": ["09:00-12:00"],
"thursday": ["09:00-12:00", "14:00-18:00"],
"friday": ["09:00-12:00"],
"saturday": [],
"sunday": []
},
"exceptions": [
{
"date": "2026-12-24",
"type": "closed",
"intervals": []
},
{
"date": "2026-12-30",
"type": "replace",
"intervals": ["09:00-11:00"]
}
]
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/users/77/working-hours', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"active": true,
"slot_duration": 30,
"horizon": {
"unit": "months",
"amount": 2
},
"weekly": {
"monday": ["09:00-12:00", "14:00-18:00"],
"tuesday": ["09:00-12:00", "14:00-18:00"],
"wednesday": ["09:00-12:00"],
"thursday": ["09:00-12:00", "14:00-18:00"],
"friday": ["09:00-12:00"],
"saturday": [],
"sunday": []
},
"exceptions": [
{
"date": "2026-12-24",
"type": "closed",
"intervals": []
},
{
"date": "2026-12-30",
"type": "replace",
"intervals": ["09:00-11:00"]
}
]
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.put(
'https://api.atys.pro/api/v1/calendar/users/77/working-hours',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'active': True,
'slot_duration': 30,
'horizon': {
'unit': 'months',
'amount': 2
},
'weekly': {
'monday': ['09:00-12:00', '14:00-18:00'],
'tuesday': ['09:00-12:00', '14:00-18:00'],
'wednesday': ['09:00-12:00'],
'thursday': ['09:00-12:00', '14:00-18:00'],
'friday': ['09:00-12:00'],
'saturday': [],
'sunday': []
},
'exceptions': [
{
'date': '2026-12-24',
'type': 'closed',
'intervals': []
},
{
'date': '2026-12-30',
'type': 'replace',
'intervals': ['09:00-11:00']
}
]
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/users/77/working-hours');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'active' => true,
'slot_duration' => 30,
'horizon' => [
'unit' => 'months',
'amount' => 2
],
'weekly' => [
'monday' => ['09:00-12:00', '14:00-18:00'],
'tuesday' => ['09:00-12:00', '14:00-18:00'],
'wednesday' => ['09:00-12:00'],
'thursday' => ['09:00-12:00', '14:00-18:00'],
'friday' => ['09:00-12:00'],
'saturday' => [],
'sunday' => []
],
'exceptions' => [
[
'date' => '2026-12-24',
'type' => 'closed',
'intervals' => []
],
[
'date' => '2026-12-30',
'type' => 'replace',
'intervals' => ['09:00-11:00']
]
]
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('PUT', 'v1/calendar/users/77/working-hours', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'active' => true,
'slot_duration' => 30,
'horizon' => [
'unit' => 'months',
'amount' => 2
],
'weekly' => [
'monday' => ['09:00-12:00', '14:00-18:00'],
'tuesday' => ['09:00-12:00', '14:00-18:00'],
'wednesday' => ['09:00-12:00'],
'thursday' => ['09:00-12:00', '14:00-18:00'],
'friday' => ['09:00-12:00'],
'saturday' => [],
'sunday' => []
],
'exceptions' => [
[
'date' => '2026-12-24',
'type' => 'closed',
'intervals' => []
],
[
'date' => '2026-12-30',
'type' => 'replace',
'intervals' => ['09:00-11:00']
]
]
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"active": true,
"slot_duration": 30,
"horizon": {
"unit": "months",
"amount": 2
},
"weekly": {
"monday": ["09:00-12:00", "14:00-18:00"],
"tuesday": ["09:00-12:00", "14:00-18:00"],
"wednesday": ["09:00-12:00"],
"thursday": ["09:00-12:00", "14:00-18:00"],
"friday": ["09:00-12:00"],
"saturday": [],
"sunday": []
},
"exceptions": [
{
"date": "2026-12-24",
"type": "closed",
"intervals": []
},
{
"date": "2026-12-30",
"type": "replace",
"intervals": ["09:00-11:00"]
}
]
}`)
req, _ := http.NewRequest("PUT", "https://api.atys.pro/api/v1/calendar/users/77/working-hours", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"user_id": 77,
"active": true,
"timezone": "America/Sao_Paulo",
"slot_duration": 30,
"min_notice_minutes": 10,
"horizon": {
"unit": "months",
"amount": 2
},
"weekly": {
"monday": [
"09:00-12:00",
"14:00-18:00"
],
"tuesday": [
"09:00-12:00",
"14:00-18:00"
],
"wednesday": [
"09:00-12:00"
],
"thursday": [
"09:00-12:00",
"14:00-18:00"
],
"friday": [
"09:00-12:00"
],
"saturday": [],
"sunday": []
},
"exceptions": [
{
"date": "2026-12-24",
"type": "closed",
"intervals": []
},
{
"date": "2026-12-30",
"type": "replace",
"intervals": [
"09:00-11:00"
]
}
],
"event_types": [
{
"id": 1,
"name": "Reunião",
"duration": null,
"effective_duration": 30,
"default": true
},
{
"id": 5,
"name": "Consulta",
"duration": 60,
"effective_duration": 60,
"default": false
}
],
"notifications": [
{
"amount": 1,
"unit": "days",
"type": "email",
"notify_contacts": true,
"send_whatsapp_to_staff": false,
"company_channel_id": null,
"meta_waba_id": null,
"waba_template": null
}
]
}
}
Precisa da permissão Configurar a agenda pública dos colaboradores. O usuário precisa ser da
empresa (404 se não for).
Horários livres
Os horários que o contato poderia reservar com o usuário num intervalo — exatamente os que a página do link de agendamento mostraria: faixas do horário de atendimento, exceções, antecedência mínima e alcance, menos os eventos que o usuário já tem na Agenda e, se ele ligou a opção usar a agenda para a disponibilidade, os horários ocupados no Google ou no Outlook.
| Parâmetro | Tipo | Descrição |
|---|---|---|
from | data ou data ISO 8601 | Início do intervalo. Default: agora. Data sozinha = início do dia. |
to | data ou data ISO 8601 | Fim do intervalo (exclusivo). Default: from + 7 dias. Data sozinha = o dia inteiro. Máximo de 62 dias por consulta (range_too_large). |
event_type_id | integer | Tipo de evento (define a duração). Default: o tipo padrão do usuário. Fora da lista dele: event_type_unavailable. |
timezone | fuso IANA | Fuso das datas da resposta (ex.: America/Manaus). Default: o da empresa. |
Exemplos de código — consultar horários livres
curl "https://api.atys.pro/api/v1/calendar/users/77/availability?from=2026-11-10&to=2026-11-10&event_type_id=1" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/users/77/availability?from=2026-11-10&to=2026-11-10&event_type_id=1', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/users/77/availability?from=2026-11-10&to=2026-11-10&event_type_id=1',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/users/77/availability?from=2026-11-10&to=2026-11-10&event_type_id=1');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/users/77/availability', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'query' => [
'from' => '2026-11-10',
'to' => '2026-11-10',
'event_type_id' => 1
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/users/77/availability?from=2026-11-10&to=2026-11-10&event_type_id=1", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"user_id": 77,
"timezone": "America/Sao_Paulo",
"organizer_timezone": "America/Sao_Paulo",
"from": "2026-11-10T00:00:00-03:00",
"to": "2026-11-11T00:00:00-03:00",
"event_type": {
"id": 1,
"name": "Reunião",
"duration": 30
},
"booking_until": "2027-01-04",
"slots": [
{
"start_at": "2026-11-10T09:00:00-03:00",
"end_at": "2026-11-10T09:30:00-03:00"
},
{
"start_at": "2026-11-10T09:30:00-03:00",
"end_at": "2026-11-10T10:00:00-03:00"
},
{
"start_at": "2026-11-10T10:30:00-03:00",
"end_at": "2026-11-10T11:00:00-03:00"
}
]
}
}
booking_until é o último dia reservável. Agenda pública desligada ou sem nenhum dia com faixa
devolvem scheduling_inactive ou availability_not_configured. Precisa da permissão
Ver horários dos colaboradores.
Reservar horário
Marca um dos horários livres em nome de um contato, pelo mesmo caminho do link público: o horário é conferido de novo na hora (duas reservas simultâneas não pegam o mesmo horário), o evento é criado na Agenda do usuário com o contato como participante, vai para o Google ou o Outlook dele quando conectado (com link do Teams, se a conta permitir), o usuário recebe a notificação, os lembretes do horário de atendimento são agendados e o contato recebe a confirmação por e-mail e WhatsApp. Por ser servidor a servidor, não há código de verificação de e-mail.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
start_at | data ISO 8601 | Sim | Início, como veio em slots[].start_at (qualquer fuso). A duração vem do tipo de evento. |
contact_id | integer | Ou contact | Contato da empresa. Não é alterado. |
contact | objeto | Ou contact_id | name e email (obrigatórios) e phone. Se já houver contato com esse e-mail na empresa, ele é usado; senão, é criado (e não fica criado se a reserva falhar). |
event_type_id | integer | Não | Tipo de evento oferecido pelo usuário. Default: o padrão. |
title | string | Não | Título do evento. Default: "Tipo com Nome do contato". |
notes | string | Não | Descrição do evento (até 2500 caracteres). |
Exemplos de código — reservar horário
curl -X POST "https://api.atys.pro/api/v1/calendar/users/77/bookings" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"start_at": "2026-11-10T10:30:00-03:00",
"contact_id": 5120,
"event_type_id": 1,
"notes": "Quer conhecer o plano anual."
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/users/77/bookings', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"start_at": "2026-11-10T10:30:00-03:00",
"contact_id": 5120,
"event_type_id": 1,
"notes": "Quer conhecer o plano anual."
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.post(
'https://api.atys.pro/api/v1/calendar/users/77/bookings',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'start_at': '2026-11-10T10:30:00-03:00',
'contact_id': 5120,
'event_type_id': 1,
'notes': 'Quer conhecer o plano anual.'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/users/77/bookings');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'start_at' => '2026-11-10T10:30:00-03:00',
'contact_id' => 5120,
'event_type_id' => 1,
'notes' => 'Quer conhecer o plano anual.'
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('POST', 'v1/calendar/users/77/bookings', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'start_at' => '2026-11-10T10:30:00-03:00',
'contact_id' => 5120,
'event_type_id' => 1,
'notes' => 'Quer conhecer o plano anual.'
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"start_at": "2026-11-10T10:30:00-03:00",
"contact_id": 5120,
"event_type_id": 1,
"notes": "Quer conhecer o plano anual."
}`)
req, _ := http.NewRequest("POST", "https://api.atys.pro/api/v1/calendar/users/77/bookings", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"event_id": 40211,
"title": "Reunião com Maria Cliente",
"description": "Quer conhecer o plano anual.",
"event_type": {
"id": 1,
"name": "Reunião"
},
"start_at": "2026-11-10T10:30:00-03:00",
"end_at": "2026-11-10T11:00:00-03:00",
"timezone": "America/Sao_Paulo",
"origin": "public_scheduling_link",
"users": [
{
"id": 77,
"name": "Carlos Vendedor"
}
],
"contacts": [
{
"id": 5120,
"name": "Maria Cliente",
"email": "maria@cliente.com.br"
}
],
"delivery_channel": "google",
"google_synced": true,
"microsoft_synced": false
}
}
event_id é o evento da Agenda. delivery_channel diz por onde o convite saiu:
google (contato com Gmail e usuário com Google conectado), microsoft ou
none (só o e-mail da Atys). A reserva aparece em Reservas da agenda pública,
como as feitas pelo link.
| Erro | Quando |
|---|---|
slot_unavailable | O horário não está (ou deixou de estar) livre, ou não cai na grade dos horários. |
invalid_contact | Contato que não é da empresa. |
event_type_unavailable | Tipo de evento que o usuário não oferece. |
scheduling_inactive / availability_not_configured | Agenda pública desligada ou sem horário. |
calendar_not_configured | A empresa não tem nenhuma agenda criada. |
Precisa da permissão Criar eventos na Agenda.
origin=public_scheduling_link — a mesma lista
da aba "Agendamentos pelo link" de Meu horário disponível.
Links de agendamento
Gera o link público para um contato escolher sozinho o horário com um usuário — o botão
Gerar link de agendamento da plataforma. O link é de uso único e vale 48 horas; enquanto
houver um link vivo para o mesmo usuário e contato, ele é devolvido de novo (200,
reused: true) em vez de criar outro, para não invalidar o que já foi enviado. A Atys não envia
o link: mande-o pelo seu canal.
Exemplos de código — gerar link de agendamento
curl -X POST "https://api.atys.pro/api/v1/calendar/scheduling-links" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"user_id": 77,
"contact_id": 5120
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/scheduling-links', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"user_id": 77,
"contact_id": 5120
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.post(
'https://api.atys.pro/api/v1/calendar/scheduling-links',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'user_id': 77,
'contact_id': 5120
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/scheduling-links');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'user_id' => 77,
'contact_id' => 5120
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('POST', 'v1/calendar/scheduling-links', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'user_id' => 77,
'contact_id' => 5120
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"user_id": 77,
"contact_id": 5120
}`)
req, _ := http.NewRequest("POST", "https://api.atys.pro/api/v1/calendar/scheduling-links", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"id": 9031,
"url": "https://app.atys.pro/schedule/Xh3k9QpL2mVb7RtY0aWc5ZeN1sFgJ8uD",
"hash": "Xh3k9QpL2mVb7RtY0aWc5ZeN1sFgJ8uD",
"status": "active",
"single_use": true,
"user": {
"id": 77,
"name": "Carlos Vendedor"
},
"contact": {
"id": 5120,
"name": "Maria Cliente"
},
"expires_at": "2026-11-06T16:30:00-03:00",
"used_at": null,
"created_at": "2026-11-04T16:30:00-03:00",
"reused": false
}
}
Usuário ou contato de outra empresa devolvem invalid_user / invalid_contact; usuário
com a agenda pública desligada, scheduling_inactive. A lista aceita os filtros
user_id, contact_id e status (active, used,
expired), com paginação (page, per_page).
Exemplos de código — listar links de agendamento
curl "https://api.atys.pro/api/v1/calendar/scheduling-links?user_id=77&status=active" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/scheduling-links?user_id=77&status=active', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/scheduling-links?user_id=77&status=active',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/scheduling-links?user_id=77&status=active');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/scheduling-links', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'query' => [
'user_id' => 77,
'status' => 'active'
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/scheduling-links?user_id=77&status=active", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": [
{
"id": 9031,
"url": "https://app.atys.pro/schedule/Xh3k9QpL2mVb7RtY0aWc5ZeN1sFgJ8uD",
"hash": "Xh3k9QpL2mVb7RtY0aWc5ZeN1sFgJ8uD",
"status": "active",
"single_use": true,
"user": {
"id": 77,
"name": "Carlos Vendedor"
},
"contact": {
"id": 5120,
"name": "Maria Cliente"
},
"expires_at": "2026-11-06T16:30:00-03:00",
"used_at": null,
"created_at": "2026-11-04T16:30:00-03:00"
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 1,
"last_page": 1
}
}
Gerar precisa da permissão Ver horários dos colaboradores ou Criar eventos na Agenda; listar, de Ver horários dos colaboradores.
Integrações Google e Microsoft
Se o usuário conectou o Google Calendar e/ou o Outlook (Microsoft 365) dele. connected é a
conta funcionando; linked: true com connected: false é uma conta que precisa ser
reconectada (auth_error diz por quê). use_for_availability indica se os
compromissos dessa agenda bloqueiam os horários livres.
Exemplos de código — status das integrações
curl "https://api.atys.pro/api/v1/calendar/users/77/calendar-integrations" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/users/77/calendar-integrations', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
const { data, error } = await response.json();
import os
import requests
response = requests.get(
'https://api.atys.pro/api/v1/calendar/users/77/calendar-integrations',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/users/77/calendar-integrations');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('GET', 'v1/calendar/users/77/calendar-integrations', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.atys.pro/api/v1/calendar/users/77/calendar-integrations", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"user_id": 77,
"google": {
"linked": true,
"connected": true,
"account_email": "carlos@gmail.com",
"use_for_availability": true,
"auth_error": null
},
"microsoft": {
"linked": true,
"connected": true,
"account_email": "carlos@loja.com.br",
"account_type": "work",
"calendar_name": "Calendário",
"supports_teams": true,
"use_for_availability": false,
"webhook_active": true,
"last_synced_at": "2026-11-04T16:10:00-03:00",
"auth_error": null
}
}
}
Conectar uma conta exige que o próprio usuário autorize no navegador, então só é feito pela
plataforma, em Configurações › Integrações. Pela mesma razão, ligar o uso para
disponibilidade e desconectar são escolhas de cada um sobre a própria conta: só valem para o usuário da
credencial ({userId} igual ao dele); para outro usuário a resposta é 403
own_account_only. {provider} é google ou microsoft; sem
conta conectada, 404 integration_not_connected.
Exemplos de código — usar agenda para a disponibilidade
curl -X PUT "https://api.atys.pro/api/v1/calendar/users/90/calendar-integrations/google/availability-preference" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"enabled": true
}'
const response = await fetch('https://api.atys.pro/api/v1/calendar/users/90/calendar-integrations/google/availability-preference', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"enabled": true
})
});
const { data, error } = await response.json();
import os
import requests
response = requests.put(
'https://api.atys.pro/api/v1/calendar/users/90/calendar-integrations/google/availability-preference',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
},
json={
'enabled': True
}
)
result = response.json()
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/users/90/calendar-integrations/google/availability-preference');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'enabled' => true
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('PUT', 'v1/calendar/users/90/calendar-integrations/google/availability-preference', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
'json' => [
'enabled' => true
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{
"enabled": true
}`)
req, _ := http.NewRequest("PUT", "https://api.atys.pro/api/v1/calendar/users/90/calendar-integrations/google/availability-preference", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
{
"data": {
"linked": true,
"connected": true,
"account_email": "integracao@gmail.com",
"use_for_availability": true,
"auth_error": null
}
}
Exemplos de código — desconectar agenda
curl -X DELETE "https://api.atys.pro/api/v1/calendar/users/90/calendar-integrations/microsoft" \
-H "Authorization: Bearer atys_live_SUA_CHAVE" \
-H "Accept: application/json"
const response = await fetch('https://api.atys.pro/api/v1/calendar/users/90/calendar-integrations/microsoft', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.ATYS_API_KEY}`,
'Accept': 'application/json'
}
});
console.log(response.status); // 204 = excluído
import os
import requests
response = requests.delete(
'https://api.atys.pro/api/v1/calendar/users/90/calendar-integrations/microsoft',
headers={
'Authorization': f"Bearer {os.environ['ATYS_API_KEY']}",
'Accept': 'application/json'
}
)
print(response.status_code) # 204 = excluído
<?php
$ch = curl_init('https://api.atys.pro/api/v1/calendar/users/90/calendar-integrations/microsoft');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('ATYS_API_KEY'),
'Accept: application/json',
],
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
<?php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.atys.pro/api/']);
$response = $client->request('DELETE', 'v1/calendar/users/90/calendar-integrations/microsoft', [
'headers' => [
'Authorization' => 'Bearer '.getenv('ATYS_API_KEY'),
'Accept' => 'application/json',
],
]);
$result = json_decode($response->getBody(), true);
package main
import (
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.atys.pro/api/v1/calendar/users/90/calendar-integrations/microsoft", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ATYS_API_KEY"))
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
Erros
Todo erro da v1 tem o mesmo formato: {"error": {"code", "message", "details"}}. Use o
code no seu tratamento; a message é para leitura humana.
422 validation_failed — dados inválidos
Campo obrigatório ausente ou com formato errado. details traz os erros por campo.
{
"error": {
"code": "validation_failed",
"message": "The start at field is required.",
"details": { "start_at": ["The start at field is required."] }
}
}
422 slot_unavailable / event_type_unavailable / scheduling_inactive / calendar_not_configured
O horário não está mais livre, o tipo de agendamento não está disponível, a agenda pública do usuário está desligada ou ele não tem calendário para reservas.
422 series_schedule_not_supported / series_date_change_not_supported / series_recurrence_immutable
Alteração que a série não aceita naquele scope — por exemplo, mudar o dia de todas as ocorrências. Veja editar evento.
422 contact_without_channel / not_a_participant / reminder_not_scheduled
Contato sem canal de contato, resposta de convite de quem não participa do evento, ou lembrete que já foi enviado.
403 own_account_only
Preferência e desconexão do Google/Microsoft só valem para a própria conta do usuário da chave.
404 not_found
O evento, usuário, contato ou item não existe ou não é visível para a chave.
403 forbidden
A chave não tem a permissão da Agenda necessária, ou o usuário API não tem a permissão na plataforma.
401 unauthenticated
Chave ausente, inválida, revogada ou expirada.