Zimun: Appointment Scheduling & Booking Service: Ejemplos de uso de la API de reservas

API

Estos ejemplos muestran flujos completos en Python, Node.js, Go y Rust. Cópialos, sustituye tus IDs y tendrás una integración funcional.

1) Obtener un token de acceso

Usa OAuth2 Client Credentials para solicitar un token de corta duración antes de llamar a cualquier API.

Python
import os
import requests

token_resp = requests.post(
    "https://api.zimun.online/oauth/token",
    auth=(os.getenv("ZIMUN_CLIENT_ID"), os.getenv("ZIMUN_CLIENT_SECRET")),
    data={"grant_type": "client_credentials"},
)
token = token_resp.json()["access_token"]
headers = {"Authorization": f"Bearer {token}"}
Node.js
import axios from "axios";

const tokenResp = await axios.post(
  "https://api.zimun.online/oauth/token",
  new URLSearchParams({ grant_type: "client_credentials" }),
  {
    auth: {
      username: process.env.ZIMUN_CLIENT_ID,
      password: process.env.ZIMUN_CLIENT_SECRET,
    },
  }
);
const token = tokenResp.data.access_token;
const headers = { Authorization: `Bearer ${token}` };
Go
client := &http.Client{}
req, _ := http.NewRequest("POST", "https://api.zimun.online/oauth/token", strings.NewReader("grant_type=client_credentials"))
req.SetBasicAuth(os.Getenv("ZIMUN_CLIENT_ID"), os.Getenv("ZIMUN_CLIENT_SECRET"))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, _ := client.Do(req)
defer resp.Body.Close()
Rust
let client = reqwest::Client::new();
let resp = client
  .post("https://api.zimun.online/oauth/token")
  .basic_auth(std::env::var("ZIMUN_CLIENT_ID")?, Some(std::env::var("ZIMUN_CLIENT_SECRET")?))
  .form(&[("grant_type", "client_credentials")])
  .send()
  .await?;
let json: serde_json::Value = resp.json().await?;
let token = json["access_token"].as_str().unwrap();

2) Listar ubicaciones

Use ubicaciones activas de reserva cuando un servicio pueda reservarse en más de un lugar o cuando su cliente deba permitir que el usuario elija explícitamente una sucursal.

Python
locations = requests.get(
    "https://api.zimun.online/api/v1/locations?page_size=50",
    headers=headers,
).json()

location_id = locations["items"][0]["id"] if locations.get("items") else None
Node.js
const locations = await axios.get(
  "https://api.zimun.online/api/v1/locations?page_size=50",
  { headers }
);

const locationId = locations.data.items?.[0]?.id || null;
Go
locationsReq, _ := http.NewRequest("GET", "https://api.zimun.online/api/v1/locations?page_size=50", nil)
locationsReq.Header.Set("Authorization", "Bearer "+token)
locationsResp, _ := client.Do(locationsReq)
defer locationsResp.Body.Close()
Rust
let locations = client
  .get("https://api.zimun.online/api/v1/locations?page_size=50")
  .bearer_auth(token)
  .send()
  .await?;

let location_body: serde_json::Value = locations.json().await?;

3) Listar servicios

Obtenga los servicios de la organización, revise los location_ids y luego elija un servicio que coincida con la ubicación seleccionada.

Python
services = requests.get(
    "https://api.zimun.online/api/v1/services?page_size=50",
    headers=headers,
).json()

first_service_id = services["items"][0]["id"] if services.get("items") else None
service_location_ids = services["items"][0].get("location_ids", []) if services.get("items") else []
Node.js
const services = await axios.get(
  "https://api.zimun.online/api/v1/services?page_size=50",
  { headers }
);

const firstServiceId = services.data.items?.[0]?.id || null;
const serviceLocationIds = services.data.items?.[0]?.location_ids || [];
Go
servicesReq, _ := http.NewRequest("GET", "https://api.zimun.online/api/v1/services?page_size=50", nil)
servicesReq.Header.Set("Authorization", "Bearer "+token)
servicesResp, _ := client.Do(servicesReq)
defer servicesResp.Body.Close()
Rust
let services = client
  .get("https://api.zimun.online/api/v1/services?page_size=50")
  .bearer_auth(token)
  .send()
  .await?;

let body: serde_json::Value = services.json().await?;

4) Obtener disponibilidad

Lea las franjas abiertas para un servicio seleccionado en una fecha concreta. Incluya location_id siempre que el servicio pueda reservarse en más de una ubicación.

Python
single_day = requests.get(
    "https://api.zimun.online/api/v1/availability?service_id=s_123&date=2026-02-20&location_id=loc_123",
    headers=headers,
).json()
Node.js
const singleDay = await axios.get(
  "https://api.zimun.online/api/v1/availability?service_id=s_123&date=2026-02-20&location_id=loc_123",
  { headers }
);
Go
availReq, _ := http.NewRequest("GET", "https://api.zimun.online/api/v1/availability?service_id=s_123&date=2026-02-20&location_id=loc_123", nil)
availReq.Header.Set("Authorization", "Bearer "+token)
availResp, _ := client.Do(availReq)
defer availResp.Body.Close()
Rust
let availability = client
  .get("https://api.zimun.online/api/v1/availability?service_id=s_123&date=2026-02-20&location_id=loc_123")
  .bearer_auth(token)
  .send()
  .await?;

5) Hold → Confirmar

Este es el flujo de confirmación de reserva después de haber seleccionado un servicio y hora válidos.

Python
# create hold
hold = requests.post(
    "https://api.zimun.online/api/v1/appointments/hold",
    headers=headers,
    json={
        "service_id": "s_123",
        "appointment_time": "2025-12-01T10:00:00Z",
        "location_id": "loc_123",
    },
).json()

# 3) confirm
confirm = requests.post(
    "https://api.zimun.online/api/v1/appointments/confirm",
    headers=headers,
    json={
        "hold_id": hold["hold_id"],
        "contact_name": "Dana Lee",
        "contact_email": "dana@example.com",
    },
).json()
Node.js
const hold = await axios.post(
  "https://api.zimun.online/api/v1/appointments/hold",
  {
    service_id: "s_123",
    appointment_time: "2025-12-01T10:00:00Z",
    location_id: "loc_123",
  },
  { headers }
);

const confirm = await axios.post(
  "https://api.zimun.online/api/v1/appointments/confirm",
  {
    hold_id: hold.data.hold_id,
    contact_name: "Dana Lee",
    contact_email: "dana@example.com",
  },
  { headers }
);
Go
// hold
holdBody := `{"service_id":"s_123","appointment_time":"2025-12-01T10:00:00Z","location_id":"loc_123"}`
holdReq, _ := http.NewRequest("POST", "https://api.zimun.online/api/v1/appointments/hold", strings.NewReader(holdBody))
holdReq.Header.Set("Authorization", "Bearer "+token)
holdReq.Header.Set("Content-Type", "application/json")
holdResp, _ := client.Do(holdReq)
Rust
let hold = client
  .post("https://api.zimun.online/api/v1/appointments/hold")
  .bearer_auth(token)
  .json(&serde_json::json!({
      "service_id": "s_123",
      "appointment_time": "2025-12-01T10:00:00Z",
      "location_id": "loc_123"
  }))
  .send()
  .await?;

6) Reprogramar o cancelar una cita

Use los endpoints /api/v1 con su bearer token para actualizar una cita existente mediante booking_id.

Python
rescheduled = requests.post(
    "https://api.zimun.online/api/v1/appointments/reschedule",
    headers=headers,
    json={
        "booking_id": "b_123",
        "start_time": "2026-02-20T13:00:00Z",
    },
).json()

cancelled = requests.post(
    "https://api.zimun.online/api/v1/appointments/cancel",
    headers=headers,
    json={"booking_id": "b_123"},
).json()
Node.js
const rescheduled = await axios.post(
  "https://api.zimun.online/api/v1/appointments/reschedule",
  { booking_id: "b_123", start_time: "2026-02-20T13:00:00Z" },
  { headers }
);

const cancelled = await axios.post(
  "https://api.zimun.online/api/v1/appointments/cancel",
  { booking_id: "b_123" },
  { headers }
);
Go
rescheduleBody := `{"booking_id":"b_123","start_time":"2026-02-20T13:00:00Z"}`
rescheduleReq, _ := http.NewRequest("POST", "https://api.zimun.online/api/v1/appointments/reschedule", strings.NewReader(rescheduleBody))
rescheduleReq.Header.Set("Authorization", "Bearer "+token)
rescheduleReq.Header.Set("Content-Type", "application/json")
rescheduleResp, _ := client.Do(rescheduleReq)
defer rescheduleResp.Body.Close()

cancelBody := `{"booking_id":"b_123"}`
cancelReq, _ := http.NewRequest("POST", "https://api.zimun.online/api/v1/appointments/cancel", strings.NewReader(cancelBody))
cancelReq.Header.Set("Authorization", "Bearer "+token)
cancelReq.Header.Set("Content-Type", "application/json")
cancelResp, _ := client.Do(cancelReq)
defer cancelResp.Body.Close()
Rust
let rescheduled = client
  .post("https://api.zimun.online/api/v1/appointments/reschedule")
  .bearer_auth(token)
  .json(&serde_json::json!({
    "booking_id": "b_123",
    "start_time": "2026-02-20T13:00:00Z"
  }))
  .send()
  .await?;

let cancelled = client
  .post("https://api.zimun.online/api/v1/appointments/cancel")
  .bearer_auth(token)
  .json(&serde_json::json!({ "booking_id": "b_123" }))
  .send()
  .await?;