Como Usar APIs Calendly: Guia do Desenvolvedor para Integração de Agendamentos

Ashley Innocent

Ashley Innocent

24 março 2026

Como Usar APIs Calendly: Guia do Desenvolvedor para Integração de Agendamentos

Resumo

As APIs do Calendly permitem automatizar fluxos de trabalho de agendamento. Você se autentica com OAuth 2.0, acessa tipos de eventos e agendamentos via api.calendly.com, e recebe atualizações em tempo real via webhooks. Para testes, use o Apidog para validar payloads de webhook e testar sua integração sem criar agendamentos reais.

Introdução

O Calendly processa milhões de reuniões mensalmente. As pessoas o utilizam para chamadas de vendas, sessões de suporte, consultorias e entrevistas. A API permite incorporar esse poder de agendamento em seus próprios aplicativos.

O padrão comum: você deseja que os agendamentos do Calendly acionem ações em seu sistema. Um usuário agenda uma demonstração, e seu CRM é atualizado. Uma consultoria é agendada, e você envia um questionário. Uma reunião é cancelada, e você notifica sua equipe.

A API do Calendly lida com isso via webhooks. Quando eventos ocorrem (agendamento criado, cancelado, reagendado), o Calendly envia POSTs para seus endpoints. Você processa o payload e age.

💡
Se você está construindo integrações de agendamento, o Apidog te ajuda a testar os manipuladores de webhook e validar os payloads. Você pode simular as respostas do Calendly durante o desenvolvimento e garantir que sua integração lida com todos os tipos de eventos antes de conectar-se a calendários reais.
botão

Autenticação com OAuth 2.0

O Calendly usa OAuth 2.0 para acesso à API. Você não pode simplesmente usar uma chave de API.

Criar um aplicativo OAuth

  1. Vá para Calendly → Integrações → API & Webhooks
  2. Clique em “Criar Novo Aplicativo”
  3. Defina sua URI de redirecionamento (por exemplo, https://yourapp.com/auth/calendly/callback)
  4. Obtenha seu ID de cliente e segredo de cliente

O fluxo OAuth

Passo 1: Redirecionar usuário para autorizar

https://auth.calendly.com/oauth/authorize?
  client_id=YOUR_CLIENT_ID&
  response_type=code&
  redirect_uri=https://yourapp.com/auth/calendly/callback

Passo 2: Usuário autoriza e é redirecionado de volta

https://yourapp.com/auth/calendly/callback?code=AUTHORIZATION_CODE

Passo 3: Trocar código por token de acesso

const response = await fetch('https://auth.calendly.com/oauth/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': 'Basic ' + Buffer.from(clientId + ':' + clientSecret).toString('base64')
  },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code: authCode,
    redirect_uri: 'https://yourapp.com/auth/calendly/callback'
  })
})

const { access_token, refresh_token, expires_in } = await response.json()

Passo 4: Usar o token

curl -X GET "https://api.calendly.com/users/me" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Tokens de atualização

Tokens de acesso expiram após 2 horas. Use tokens de atualização para obter novos:

const response = await fetch('https://auth.calendly.com/oauth/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': 'Basic ' + Buffer.from(clientId + ':' + clientSecret).toString('base64')
  },
  body: new URLSearchParams({
    grant_type: 'refresh_token',
    refresh_token: storedRefreshToken
  })
})

Obtendo informações do usuário

Obter usuário atual

curl -X GET "https://api.calendly.com/users/me" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Resposta:

{
  "resource": {
    "avatar_url": "https://calendly.com/avatar.jpg",
    "created_at": "2024-01-15T10:00:00Z",
    "current_organization": "https://api.calendly.com/organizations/ABC123",
    "email": "you@example.com",
    "name": "John Doe",
    "scheduling_url": "https://calendly.com/johndoe",
    "slug": "johndoe",
    "timezone": "America/New_York",
    "uri": "https://api.calendly.com/users/ABC123"
  }
}

Obter associação à organização

curl -X GET "https://api.calendly.com/organization_memberships/me" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Tipos de evento

Tipos de evento são os modelos de reunião que os usuários criam (chamada de 30 min, consultoria de 60 min, etc.).

Listar tipos de evento

curl -X GET "https://api.calendly.com/event_types?user=https://api.calendly.com/users/ABC123" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Resposta:

{
  "resource": {
    "uri": "https://api.calendly.com/event_types/ETC123",
    "active": true,
    "booking_method": "instant",
    "color": "#0066FF",
    "created_at": "2024-01-15T10:00:00Z",
    "description_html": "<p>30-minute consultation</p>",
    "duration": 30,
    "internal_note": "Use Zoom link",
    "kind": "solo",
    "name": "30 Min Consultation",
    "pooling_type": null,
    "profile": {
      "name": "John Doe",
      "type": "User",
      "owner": "https://api.calendly.com/users/ABC123"
    },
    "scheduling_url": "https://calendly.com/johndoe/30min",
    "slug": "30min",
    "type": "StandardEventType"
  },
  "pagination": {
    "count": 1,
    "next_page": null
  }
}

Obter um tipo de evento específico

curl -X GET "https://api.calendly.com/event_types/ETC123" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Eventos agendados (agendamentos)

Eventos são os agendamentos reais feitos através do Calendly.

Listar eventos agendados

curl -X GET "https://api.calendly.com/scheduled_events?user=https://api.calendly.com/users/ABC123" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Filtrar por intervalo de datas:

curl -X GET "https://api.calendly.com/scheduled_events?min_start_time=2026-03-01T00:00:00Z&max_start_time=2026-03-31T23:59:59Z" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Resposta:

{
  "resource": {
    "uri": "https://api.calendly.com/scheduled_events/ABC123",
    "status": "active",
    "tracking": {
      "utm_campaign": "spring_sale",
      "utm_source": "email",
      "utm_medium": "newsletter"
    },
    "created_at": "2026-03-24T10:00:00Z",
    "end_time": "2026-03-25T11:00:00Z",
    "event_type": "https://api.calendly.com/event_types/ETC123",
    "invitees_counter": {
      "active": 1,
      "limit": 1,
      "total": 1
    },
    "location": {
      "type": "zoom",
      "join_url": "https://zoom.us/j/123456789"
    },
    "start_time": "2026-03-25T10:30:00Z",
    "updated_at": "2026-03-24T10:00:00Z"
  }
}

Obter detalhes do evento

curl -X GET "https://api.calendly.com/scheduled_events/EVENT_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Obter convidados para um evento

curl -X GET "https://api.calendly.com/scheduled_events/EVENT_ID/invitees" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Resposta:

{
  "resource": [
    {
      "cancel_url": "https://calendly.com/cancellations/ABC123",
      "created_at": "2026-03-24T10:00:00Z",
      "email": "jane@example.com",
      "event": "https://api.calendly.com/scheduled_events/ABC123",
      "name": "Jane Smith",
      "new_invitee": null,
      "old_invitee": null,
      "reschedule_url": "https://calendly.com/reschedulings/ABC123",
      "status": "active",
      "text_reminder_number": "+15551234567",
      "timezone": "America/New_York",
      "tracking": {
        "utm_campaign": null,
        "utm_source": null
      },
      "updated_at": "2026-03-24T10:00:00Z",
      "uri": "https://api.calendly.com/scheduled_event_invitees/INV123",
      "canceled": null
    }
  ]
}

Webhooks para atualizações em tempo real

Webhooks notificam seu aplicativo sobre eventos de agendamento em tempo real.

Criar uma assinatura de webhook

curl -X POST "https://api.calendly.com/webhook_subscriptions" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/webhooks/calendly",
    "events": [
      "invitee.created",
      "invitee.canceled",
      "invitee.rescheduled"
    ],
    "organization": "https://api.calendly.com/organizations/ORG123",
    "scope": "organization"
  }'

Eventos disponíveis:

Listar assinaturas de webhook

curl -X GET "https://api.calendly.com/webhook_subscriptions?organization=https://api.calendly.com/organizations/ORG123" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Excluir um webhook

curl -X DELETE "https://api.calendly.com/webhook_subscriptions/WEBHOOK_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Manipulando payloads de webhook

Verificar assinaturas de webhook

O Calendly assina os webhooks com uma assinatura no cabeçalho Calendly-Webhook-Signature:

import crypto from 'crypto'

function verifySignature(payload, signature, secret) {
  const [t, v1] = signature.split(',')
  const timestamp = t.split('=')[1]
  const hash = v1.split('=')[1]
  
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(timestamp + '.' + payload)
    .digest('hex')
  
  return crypto.timingSafeEqual(
    Buffer.from(hash),
    Buffer.from(expectedSignature)
  )
}

app.post('/webhooks/calendly', (req, res) => {
  const signature = req.headers['calendly-webhook-signature']
  const payload = JSON.stringify(req.body)
  
  if (!verifySignature(payload, signature, process.env.CALENDLY_WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature')
  }
  
  // Process webhook
  handleWebhook(req.body)
  res.status(200).send('OK')
})

Processar eventos de agendamento

function handleWebhook(payload) {
  const { event, payload: data } = payload
  
  switch (event) {
    case 'invitee.created':
      console.log(`New booking: ${data.event.start_time}`)
      console.log(`Invitee: ${data.email}`)
      // Add to CRM, send confirmation email, etc.
      syncToCRM(data)
      break
      
    case 'invitee.canceled':
      console.log(`Booking canceled: ${data.event.uri}`)
      // Update CRM, notify team, etc.
      removeFromCRM(data)
      break
      
    case 'invitee.rescheduled':
      console.log(`Booking rescheduled: ${data.event.start_time}`)
      // Update calendar, notify team, etc.
      updateCRM(data)
      break
  }
}

Testando com Apidog

A API do Calendly requer OAuth, o que complica os testes. O Apidog simplifica isso.

image-237.png

1. Simular respostas OAuth

Durante o desenvolvimento, não passe pelo fluxo OAuth completo toda vez. Simule a resposta do token:

{
  "access_token": "mock_access_token",
  "refresh_token": "mock_refresh_token",
  "expires_in": 7200,
  "created_at": 1700000000
}

2. Testar manipuladores de webhook

Crie payloads de webhook simulados:

{
  "created_at": "2026-03-24T10:00:00Z",
  "event": "invitee.created",
  "payload": {
    "email": "test@example.com",
    "name": "Test User",
    "event": {
      "start_time": "2026-03-25T10:30:00Z",
      "end_time": "2026-03-25T11:00:00Z",
      "event_type": {
        "name": "30 Min Consultation"
      }
    }
  }
}

Envie para seu endpoint de webhook e verifique o processamento.

3. Variáveis de ambiente

CALENDLY_CLIENT_ID: abc123
CALENDLY_CLIENT_SECRET: xyz789
CALENDLY_ACCESS_TOKEN: stored_token
CALENDLY_REFRESH_TOKEN: stored_refresh
CALENDLY_WEBHOOK_SECRET: webhook_signing_secret

4. Validar assinaturas de webhook

pm.test('Webhook signature is valid', () => {
  const signature = pm.request.headers.get('Calendly-Webhook-Signature')
  pm.expect(signature).to.exist
  
  const payload = pm.request.body.raw
  const secret = pm.environment.get('CALENDLY_WEBHOOK_SECRET')
  
  // Verify signature
  const valid = verifySignature(payload, signature, secret)
  pm.expect(valid).to.be.true
})

Teste os webhooks do Calendly com o Apidog - grátis

Erros comuns e soluções

401 Não Autorizado

Causa: Token inválido ou expirado.

Solução:

  1. Verifique se o token não expirou (expira em 2 horas)
  2. Use o token de atualização para obter um novo token de acesso
  3. Garanta que o cabeçalho Authorization seja Bearer {token}

403 Proibido

Causa: Escopo OAuth insuficiente.

Solução: O token OAuth precisa de escopos apropriados. Ao solicitar autorização, inclua os escopos necessários. Os escopos do Calendly são implícitos com base no que o usuário autoriza.

404 Não Encontrado

Causa: O recurso não existe ou o usuário não tem acesso.

Solução:

  1. Verifique se a URI do recurso está correta
  2. Garanta que o usuário autenticado tenha acesso ao recurso
  3. Verifique se o tipo de evento ou ID do evento é válido

422 Entidade Não Processável

Causa: Erro de validação na requisição.

Solução: Verifique a resposta para detalhes:

{
  "title": "Validation Error",
  "message": "Invalid parameter: url must be a valid HTTPS URL"
}

Alternativas e comparações

Recurso Calendly Acuity Cal.com Calendly
Camada gratuita Limitada Limitada Auto-hospedado grátis
Acesso à API
Webhooks
OAuth Chave de API Chave de API OAuth
Agendamento em equipe
Código aberto Não Não Sim Não

O Calendly possui a documentação de API e o fluxo OAuth mais polidos. O Cal.com é a alternativa de código aberto com autenticação por chave de API mais simples.

Casos de uso do mundo real

Integração com CRM de vendas. Uma empresa SaaS B2B incorpora o Calendly em sua página de preços. Quando alguém agenda uma demonstração, o webhook aciona:

  1. Criação de lead no Salesforce
  2. Envio de notificação Slack para a equipe de vendas
  3. Adição à sequência de automação de marketing
  4. Registro de atividade na plataforma de sucesso do cliente

Plataforma de consultoria. Uma plataforma de serviços jurídicos permite que clientes agendem consultorias com advogados. A integração da API:

  1. Sincroniza agendamentos com o sistema de agendamento interno
  2. Gera links de reunião do Zoom
  3. Envia questionário de admissão 24 horas antes
  4. Cria arquivo de caso quando a reunião é concluída

Agendamento de entrevistas. Uma plataforma de recrutamento usa o Calendly para entrevistas de candidatos. Webhooks:

  1. Atualizam o ATS com detalhes da entrevista
  2. Notificam o gerente de contratação por e-mail
  3. Enviam convites de calendário para todos os participantes
  4. Rastreiam ausências para acompanhamento

Conclusão

Aqui está o que você aprendeu:

Seus próximos passos:

  1. Crie um aplicativo OAuth no Calendly
  2. Implemente o fluxo OAuth
  3. Configure uma assinatura de webhook
  4. Teste com payloads simulados no Apidog
  5. Implante em produção

Teste os webhooks do Calendly com o Apidog - grátis

Perguntas Frequentes

Preciso de um plano pago do Calendly para usar a API?Não. A API está disponível em todos os planos, incluindo o gratuito. No entanto, os planos gratuitos têm recursos limitados. Webhooks estão disponíveis em todos os planos.

Qual a diferença entre webhooks de nível de usuário e de nível de organização?Webhooks de nível de usuário capturam eventos apenas para um usuário. Webhooks de nível de organização capturam eventos para todos os membros da equipe. A maioria das integrações usa o escopo de organização.

Como obtenho o segredo de assinatura do webhook?Quando você cria um webhook via API, a resposta inclui uma signing_key. Armazene isso com segurança. É usado para verificar as assinaturas do webhook.

Posso criar agendamentos via API?Não. O Calendly não possui um endpoint de API para criar agendamentos. Os agendamentos devem ocorrer através da UI do Calendly ou de widgets incorporados. A API é somente leitura para agendamentos.

Como lido com conversões de fuso horário?Todos os timestamps na API estão em UTC (ISO 8601). Converta para a hora local em seu aplicativo. O fuso horário do usuário está disponível no recurso de usuário.

Qual é o limite de taxa?O Calendly não documenta publicamente os limites de taxa. Use padrões de requisição razoáveis. Se você atingir os limites, implemente um backoff exponencial.

Posso obter agendamentos históricos?Sim. Use min_start_time e max_start_time para consultar eventos históricos. Não há limite de quão longe no passado você pode consultar.

Como testo o fluxo OAuth localmente?Use um serviço de tunelamento como o ngrok para expor seu servidor local. Defina a URI de redirecionamento para sua URL ngrok. Complete o fluxo OAuth em um navegador, então inspecione o callback.

Pratique o design de API no Apidog

Descubra uma forma mais fácil de construir e usar APIs