Jos sinulla on varauksiin perustuva yritys, tarvitset todennäköisesti varaustietosi useammassa kuin yhdessä paikassa. CRM:n on tiedettävä, kun uusi asiakas varaa. ERP tarvitsee tulotiedot. Markkinointityökalusi tulee käynnistää tervetuloviesti. Mukautetun sovelluksesi on luotava varaukset ohjelmallisesti.
Cowlendarin Julkinen API ja Webhooks tekevät kaiken tämän mahdolliseksi. API:n avulla voit lukea palvelujasi ja varauksiasi sekä luoda uusia varauksia mistä tahansa ulkoisesta järjestelmästä. Webhooks lähettää reaaliaikaisia ilmoituksia palvelimellesi aina, kun jotain tapahtuu: varaus luodaan, vahvistetaan, peruutetaan, ajoitetaan uudelleen tai tilaustapahtuma tapahtuu.
Molemmat ominaisuudet ovat tällä hetkellä Beta.
Mitä voit rakentaa Cowlendar API:lla?
Tässä on todellisia integraatioskenaarioita, joita Cowlendar-kauppiaat rakentavat juuri nyt:
Synkronoi jokainen varauksesi HubSpotiin, Salesforceen tai mihin tahansa CRM:ään. Kun asiakas varaa hiustenleikkauksen, joogatunnin tai vuokrauksen, webhook käynnistyy välittömästi ja sisältää kaikki varaustiedot (nimi, sähköpostiosoite, puhelinnumero, palvelu, päivämäärä, hinta, tiimin jäsen). CRM luo tai päivittää yhteystiedon automaattisesti ilman manuaalista tietojen syöttämistä. Rakenna oma varaussivusi tai mobiilisovellus. Käytä APIa palveluiden hakemiseen, mukaan lukien kestot, tiimin jäsenet, varusteet ja osallistujaluokat, ja luo varauksia omasta käyttöliittymästäsi. Varaus käynnistää samat vahvistussähköpostit, tekstiviesti-ilmoitukset ja Google Calendar-synkronoinnin kuin kaikki Cowlendar-widgetin kautta tehdyt varaukset. Automatisoi työnkulku Zapierilla tai Makella ilman koodia. Osoita Cowlendar-webhook Zapier- tai Make webhook -URL-osoitteeseen. Jokaisesta varaustapahtumasta tulee laukaisu. Lähetä Slack-ilmoitus, kun joku tekee varauksia, lisää rivin Google Sheetsiin, luo Trello-kortin tai käynnistää sähköpostisarjan Klaviyossa tai Mailchimpissa. Syötä varaustiedot raportointi- tai BI-työkaluusi. List Bookings -päätepisteen avulla voit hakea kaikki varaukset tietyltä ajanjaksolta tilan, palvelun, läsnäolon tai asiakkaan sähköpostin perusteella suodatettuna. Vie tietovarastoon, Google Sheetsiin tai Airtableen mukautettuja hallintapaneeleja varten. Linkitä varaukset tilaushyvityksiin. Kun luot varausta API:n kautta, välitä subscription_id, jotta asiakkaan suunnitelmasta vähennetään automaattisesti yksi saldo, esimerkiksi 10 luokan joogapassi. Yhdistä myyntipiste- tai järjestelmänvalvojan varaukset ulkoisiin järjestelmiin. Webhookit käynnistyvät kaikista varauslähteistä: myymälän widgetistä, hallintapaneelista, myyntipisteestä ja itse API:sta. Mikään ei putoa halkeamien läpi.
Todennus
Jokainen API-pyyntö vaatii Cowlendar-järjestelmänvalvojaltasi luoman Bearer-tunnuksen. Tokeneilla on täysi luku- ja kirjoitusoikeus myymäläsi varauksiin ja palveluihin. Käsittele niitä kuin salasanoja: älä sitoa niitä versionhallintaan tai jaa niitä julkisissa kanavissa.
API-tunnuksen luominen
Vaihe 1: Avaa Shopify-järjestelmänvalvojassasi Cowlendar -sovellus.
Vaihe 2: Siirry osoitteeseen Settings > Public API.
Vaihe 3: Napsauta Generate token.
Vaihe 4: Anna tunnuksellesi kuvaava nimi, jotta voit tunnistaa sen myöhemmin, esimerkiksi "HubSpot sync", "Zapier" tai "Mobile app".
Vaihe 5: Napsauta Generate . Cowlendar näyttää sinulle täyden tunnuksen vain kerran. Kopioi se välittömästi ja tallenna se turvalliseen paikkaan, kuten salasananhallintaohjelmaan tai palvelimesi ympäristömuuttujiin.
Voit peruuttaa minkä tahansa tunnuksen milloin tahansa samalta sivulta. Tokenin peruuttaminen lopettaa välittömästi kaikki sitä käyttävät API-pyynnöt.
Tokenin käyttäminen
Sisällytä tunnus jokaisen API-pyynnön Authorization-otsikkoon:
Authorization: Bearer YOUR_TOKEN_HERE
Esimerkki kiharalla:
curl https://app.cowlendar.com/public-api/v1/services -H "Authorization: Bearer YOUR_TOKEN_HERE"
Jos tunnus puuttuu tai virheellinen, API palauttaa 401.
API-päätepisteet
Perus-URL-osoite: https://app.cowlendar.com
Listaa palvelut
GET /public-api/v1/services
Palauttaa kaikki ei-arkistoidut palvelut kaupassasi. Käytä tätä päätepistettä löytääksesi palvelutunnuksesi, tyypit, kestot, tiimin jäsenet, varusteet ja osallistujaluokat ennen varausten luomista API:n kautta.
Kyselyparametrit:
limit (valinnainen, 1-100): tulosten määrä sivua kohden.
cursor (valinnainen): sivutuskohdistin edellisestä vastauksesta.
is_active (valinnainen, tosi tai epätosi): suodata aktiivisten tai ei-aktiivisten palveluiden mukaan.
type (valinnainen): suodata palvelutyypin mukaan. Arvot: classic-checkout, classic-no-checkout, multiday-checkout, multiday-no-checkout, multislot-checkout, multislot-no-checkout, fullday-checkout, fullday-no-checkout.
q (valinnainen, enintään 120 merkkiä): hakupalvelut otsikon perusteella.
sort (valinnainen): -id (oletus, uusin ensin), id (vanhin ensin), title (A - Z), -title (Z - A).
Esimerkkipyyntö:
curl "https://app.cowlendar.com/public-api/v1/services?is_active=true&limit=10" -H "Authorization: Bearer YOUR_TOKEN_HERE"
Esimerkkivastaus (lyhennetty):
{
"data": [
{
"id": "6789abcdef0123456789abcd",
"title": "Haircut",
"type": "classic-checkout",
"is_active": true,
"timezone": "Europe/Paris",
"durations": [30, 45, 60],
"default_duration": 30,
"avs_type": "teammates",
"meeting_location": "in_person",
"enable_participants": false,
"participants": [],
"equipments": [],
"teammates": [
{
"id": "aaa111bbb222ccc333ddd444",
"firstname": "Marie",
"lastname": "Dupont",
"email": "[email protected]",
"thumbnail": null
}
],
"product": {
"handle": "haircut",
"title": "Haircut",
"image": "https://cdn.shopify.com/..."
},
"created_at": "2025-09-01T10:00:00.000Z",
"updated_at": "2026-05-10T08:30:00.000Z"
}
],
"pagination": {
"has_more": false,
"next_cursor": null
}
}
Keskeisten palvelualojen ymmärtäminen
avs_type kertoo, kuinka tämä palvelu hallitsee saatavuutta ja määrittää, onko sinun läpäistävä teammate_id varauksia luodessasi:
avs_type: "teammates" tarkoittaa, että jokaisella tiimin jäsenellä on oma itsenäinen aikataulunsa. Kun luot varausta, välitä teammate_id teammates-taulukosta. Jos jätät sen pois, kaupan omistajaa käytetään varavarana.
avs_type: "service" tarkoittaa, että palvelu itse omistaa saatavuuden. Nimetty tiimin jäsen määritetään automaattisesti varausajasta lähtien. Voit silti siirtää teammate_id:n pakottaaksesi tietyn henkilön.
avs_type: "equipment" tarkoittaa, että saatavuus on laitekohtaista. Samanlainen kuin huoltotila, mutta sidottu laitekapasiteettiin.
enable_participants kertoo, käyttääkö palvelu kirjoitettuja osallistujaluokkia, kuten "aikuinen", "lapsi" tai "vanhempi". Kun true, participants-taulukko sisältää luokat ja niiden tunnukset, minimi- ja enimmäismäärät sekä oletusarvot. Tarvitset näitä tunnuksia, kun luot varauksia yksityiskohtaisella osallistujaerittelyllä. varusteet sisältää varattavissa olevia resursseja, kuten huoneita, kenttiä, ajoneuvoja tai polkupyöriä niiden muunnelmilla ja SKU:illa. Laitteissa, joissa on tracking_type: "same", kaikki yksiköt ovat vaihdettavissa ja voit käyttää mitä tahansa SKU:ta, tyypillisesti base. tracking_type: "unique":ssä jokaisella yksiköllä on oma SKU, ja sinun on valittava mallista variants[].sku. tyyppi kertoo varausmallin. Pääte -checkout tai -no-checkout ilmaisee, käyttääkö palvelu Shopify checkoutia. Etuliite ilmaisee aikataulumallin: classic yhdelle aikavälille, multiday useille päiville, kuten hotellimajoituksille, multislot useille peräkkäisille jaksoille ja fullday koko päivän varauksille.
Listaa varaukset
GET /public-api/v1/bookings
Palauttaa myymäläsi varaukset. Tämä on päätepiste, jota käytät CRM-synkronointiin, vientiraporttien ja mukautettujen varausten hallintapaneeleihin.
Kyselyparametrit:
limit (valinnainen, 1-100): tulokset per sivu.
cursor (valinnainen): sivutuskohdistin.
start (valinnainen, ISO 8601 datetime): vain varaukset, jotka alkavat tästä päivämäärästä tai sen jälkeen.
end (valinnainen, ISO 8601 datetime): vain ennen tätä päivämäärää alkavat varaukset.
service_id (valinnainen, joukko ID): suodata yhden tai useamman palvelun mukaan.
subscription_id (valinnainen, joukko ID): suodata tilausten mukaan.
status (valinnainen, ryhmä): confirmed, pending, declined, canceled.
attendance (valinnainen, ryhmä): booked, pending, arrived, started, completed, no-show, delayed, paid.
customer_email (valinnainen): suodata tarkan asiakkaan sähköpostin mukaan.
sort (valinnainen): -id (oletus, uusin ensin), id (vanhin ensin), start_date (vanhin ensin), -start_date (uusin ensin).
Esimerkki: hanki kaikki vahvistetut varaukset ensi viikolle:
curl "https://app.cowlendar.com/public-api/v1/bookings?status=confirmed&start=2026-05-25T00:00:00Z&end=2026-06-01T00:00:00Z&sort=start_date" -H "Authorization: Bearer YOUR_TOKEN_HERE"
Esimerkki: etsi kaikki varaukset tietylle asiakkaalle:
curl "https://app.cowlendar.com/public-api/v1/[email protected]" -H "Authorization: Bearer YOUR_TOKEN_HERE"
Esimerkki: vie kaikki ei-show't tietystä palvelusta:
curl "https://app.cowlendar.com/public-api/v1/bookings?attendance=no-show&service_id=6789abcdef0123456789abcd" -H "Authorization: Bearer YOUR_TOKEN_HERE"
Esimerkkivastaus (lyhennetty):
{
"data": [
{
"id": "abc123def456ghi789jkl012",
"booking_str": "COW-1234",
"service": {
"id": "6789abcdef0123456789abcd",
"title": "Haircut",
"type": "classic-checkout"
},
"start_date": "2026-05-27T14:00:00.000Z",
"end_date": "2026-05-27T14:30:00.000Z",
"timezone": "Europe/Paris",
"customer": {
"name": "Jane Smith",
"email": "[email protected]",
"phone": "+33612345678",
"locale": "en"
},
"form_data": {
"Special requests": "Window seat"
},
"quantity": 1,
"unit_quantity": 1,
"quantity_details": [],
"price": { "amount": 35, "currency": "EUR" },
"confirmation_status": "confirmed",
"attendance": "booked",
"financial_status": "paid",
"is_canceled": false,
"teammates": [
{
"id": "aaa111bbb222ccc333ddd444",
"firstname": "Marie",
"lastname": "Dupont"
}
],
"order_id": "gid://shopify/Order/123456789",
"subscription_id": null,
"created_at": "2026-05-20T09:15:00.000Z",
"updated_at": "2026-05-20T09:15:00.000Z"
}
],
"pagination": {
"has_more": false,
"next_cursor": null
}
}
Keskeisten varauskenttien ymmärtäminen
määrä ja yksikkömäärä toimivat yhdessä. Klassisessa palvelussa, kuten hiustenleikkauksessa, quantity on osallistuvien asiakkaiden määrä ja unit_quantity on 1. Monipäiväisissä palveluissa, kuten hotellimajoituksessa, quantity on huoneiden lukumäärä ja unit_quantity on öiden lukumäärä. Usean paikan palvelussa quantity on aina 1 ja unit_quantity on varattujen paikkojen lukumäärä. Laskutettavat yksiköt ovat aina quantity x unit_quantity. quantity_details on yksityiskohtainen erittely. Se voi sisältää kolmen tyyppisiä merkintöjä: default anonyymille luvulle, participant kirjoitetulle osallistujalle, kuten "aikuinen" tai "lapsi", tai equipment varattavissa olevalle resurssille, kuten "Court 3". Vanhoilla varauksilla voi olla tyhjä joukko tässä. confirmation_status on confirmed, pending tai declined. Jotkut palvelut vaativat järjestelmänvalvojan manuaalisen vahvistuksen ennen kuin varaus aktivoituu. attendance seuraa asiakkaan läsnäolon elinkaarta: booked, pending, arrived, started, completed, no-show, delayed, paid. order_id on Shopify tilaustunnus, kun varaus meni Shopify kassalla. Se on null manuaalisiin varauksiin ja API:n luomiin varauksiin. subscription_id linkittää varauksen tilaussuunnitelmaan, esimerkiksi 10 luokan lippuun.
Luo varaus API:n kautta
POST /public-api/v1/bookings
Luo varauksen ohjelmallisesti. Tätä käsitellään manuaalisena varauksena, mikä tarkoittaa, että Shopify-tilausta ei luoda. Kaikki tavalliset automaatiot laukeavat kuitenkin edelleen normaalisti: vahvistussähköpostit asiakkaalle, ilmoitussähköpostit ja tekstiviestit tiimille sekä kalenterin synkronointi Google Calendar:n tai Outlook:n kanssa.
Tätä päätepistettä käytät, kun rakennat mukautetun varauskäyttöliittymän, mobiilisovellus:n, kioskin tai tuodessasi varauksia toisesta järjestelmästä.
Pakolliset kentät:
service_id (merkkijono): palvelun tunnus, jonka saat List Services -palvelusta.
start_date (ISO 8601 datetime): milloin varaus alkaa.
end_date (ISO 8601 datetime): kun varaus päättyy.
timezone (merkkijono): IANA aikavyöhyke, esimerkiksi Europe/Paris, America/New_York, Asia/Tokyo.
customer (objekti): sisältää vähintään email tai phone. Se voi sisältää myös name, firstname, lastname ja locale, joka on asiakkaan ilmoitussähköpostien kielikoodi.
Valinnaiset kentät:
quantity (kokonaisluku, oletusarvo 1): ylimmän tason yksiköt varattu. Ohitetaan, jos quantity_details on toimitettu.
unit_quantity (kokonaisluku, oletusarvo 1): alayksiköt ylätason yksikköä kohti.
quantity_details (ryhmä): yksityiskohtainen erittely osallistujatyypin tai laitteiden mukaan. Kun quantity on annettu, se lasketaan automaattisesti summana.
teammate_id (merkkijono): pakota tietty tiimin jäsen.
subscription_id (merkkijono): linkitä tämä varaus olemassa olevaan tilaukseen ja vähennä yksi saldo.
form_data (objekti): mukautetut avain- tai arvoparit varauslomakkeestasi.
price (numero, oletusarvo 0): varauksen kokonaishinta.
currency (merkkijono): ISO 4217 -koodi, kuten USD, EUR tai GBP. Oletusarvo on myymäläsi valuutta.
Esimerkki: luo yksinkertainen varaus
Asiakas varaa 30 minuutin hiustenleikkauksen tietyn stylistin kanssa:
curl -X POST https://app.cowlendar.com/public-api/v1/bookings -H "Authorization: Bearer YOUR_TOKEN_HERE" -H "Content-Type: application/json" -d '{
"service_id": "6789abcdef0123456789abcd",
"start_date": "2026-06-01T10:00:00.000Z",
"end_date": "2026-06-01T10:30:00.000Z",
"timezone": "Europe/Paris",
"customer": {
"email": "[email protected]",
"name": "John Doe",
"phone": "+33612345678",
"locale": "en"
},
"teammate_id": "aaa111bbb222ccc333ddd444",
"quantity": 1,
"price": 35,
"currency": "EUR"
}'
Cowlendar luo varauksen ja käynnistää vahvistussähköpostin, tekstiviestin ja kalenterikutsun sekä asiakkaalle että tiimin jäsenelle.
Esimerkki: ryhmävaraus kirjoitetuilla osallistujilla
Perhe varaa opastetun kierroksen: 3 aikuista ja 2 lasta eri hintaluokissa:
curl -X POST https://app.cowlendar.com/public-api/v1/bookings -H "Authorization: Bearer YOUR_TOKEN_HERE" -H "Content-Type: application/json" -d '{
"service_id": "6789abcdef0123456789abcd",
"start_date": "2026-06-15T09:00:00.000Z",
"end_date": "2026-06-15T11:00:00.000Z",
"timezone": "America/New_York",
"customer": {
"email": "[email protected]",
"firstname": "Sarah",
"lastname": "Miller",
"phone": "+15551234567",
"locale": "en"
},
"quantity_details": [
{
"type": "participant",
"name": "Adult",
"quantity": 3,
"participant_id": "adult_id_from_service"
},
{
"type": "participant",
"name": "Child (under 12)",
"quantity": 2,
"participant_id": "child_id_from_service"
}
],
"price": 175,
"currency": "USD"
}'
participant_id-arvot tulevat palvelun participants[]-taulukosta List Services -vastauksessa. Kokonais-quantity asetetaan automaattisesti arvoon 5 (3 + 2).
Esimerkki: varaus varusteineen
Asiakas varaa tenniskentän 1 tunniksi:
curl -X POST https://app.cowlendar.com/public-api/v1/bookings -H "Authorization: Bearer YOUR_TOKEN_HERE" -H "Content-Type: application/json" -d '{
"service_id": "6789abcdef0123456789abcd",
"start_date": "2026-06-10T16:00:00.000Z",
"end_date": "2026-06-10T17:00:00.000Z",
"timezone": "Europe/London",
"customer": {
"email": "[email protected]",
"name": "Tom Wilson"
},
"quantity_details": [
{
"type": "equipment",
"name": "Court 3",
"quantity": 1,
"equipment_id": "eee555fff666ggg777hhh888",
"equipment_sku": "COURT3",
"capacity": 4
}
],
"price": 25,
"currency": "GBP"
}'
equipment_id ja equipment_sku tulevat palvelun equipments[]-ryhmästä. Jos laitteissa on tracking_type: "same", käytä mitä tahansa SKU:ta, yleensä base. Käytä tracking_type: "unique":ää varten haluamaasi yksikköä variants[].sku.
Esimerkki: tilauslinkitetty varaus
Joogastudion jäsen käyttää yhden hyvityksen kuukausittaisesta 10 luokan passistaan:
curl -X POST https://app.cowlendar.com/public-api/v1/bookings -H "Authorization: Bearer YOUR_TOKEN_HERE" -H "Content-Type: application/json" -d '{
"service_id": "6789abcdef0123456789abcd",
"start_date": "2026-06-05T08:00:00.000Z",
"end_date": "2026-06-05T09:00:00.000Z",
"timezone": "America/Los_Angeles",
"customer": {
"email": "[email protected]",
"name": "Lisa Chen",
"locale": "en"
},
"subscription_id": "fff000eee111ddd222ccc333",
"price": 0
}'
Tilauksen on oltava active, kuuluttava samaan palveluun ja oltava remaining_credits > 0. Cowlendar vähentää automaattisesti luottomäärää ja lähettää tilauksen päivityssähköpostin asiakkaalle.
Virhekoodit
400 Vahvistusvirhe. Pakollinen kenttä puuttuu tai on väärässä muodossa. Virheteksti kertoo, mikä kenttä.
401 Token puuttuu tai virheellinen.
403 Kauppa ei ole aktiivinen tai pääsyä on rajoitettu.
404 Palvelua ei löydy.
422 Varaus hylätty. Aika on jo varattu, tiimin jäsen ei ole tavoitettavissa, laitteet ovat täynnä tai tilauksessa ei ole jäljellä krediittejä. Tarkista virheilmoituksesta tietty syy.
429 Nopeuden raja ylitetty. Välitä pyyntöihisi ja yritä hetken kuluttua uudelleen.
Sivutus
Kaikki luettelon päätepisteet käyttävät kohdistinpohjaista sivutusta. Kun vastaus sisältää "has_more": true, välitä next_cursor-arvo cursor-parametriksi seuraavassa pyynnössäsi:
curl "https://app.cowlendar.com/public-api/v1/bookings?cursor=eyJpZCI6IjY3ODlhYmNkIn0=&limit=50" -H "Authorization: Bearer YOUR_TOKEN_HERE"
Lajittelujärjestys säilyy sivujen välillä. Sivun enimmäiskoko on 100 tulosta.
Webhooks: reaaliaikaiset varausilmoitukset
Sovellusliittymän avulla voit noutaa tietoja pyynnöstä, mutta webhookit välittävät tiedot sinulle välittömästi. Aina kun varaus luodaan, vahvistetaan, peruutetaan tai ajoitetaan uudelleen, Cowlendar lähettää allekirjoitetun HTTP POST:n määrittämääsi URL-osoitteeseen.
Webhookit ovat välttämättömiä reaaliaikaisten integraatioiden rakentamisessa: CRM-synkronointi, Slack-ilmoitukset, automatisoidut sähköpostisarjat, live-hallintapaneelit tai mikä tahansa työnkulku, jonka on reagoitava varaustapahtumiin niiden tapahtuessa.
Määritä webhook-päätepiste
Vaihe 1: Avaa Shopify-järjestelmänvalvojassasi Cowlendar -sovellus.
Vaihe 2: Siirry osoitteeseen Settings > Webhooks.
Vaihe 3: Napsauta Add endpoint.
Vaihe 4: Anna päätepisteellesi nimi, esimerkiksi "HubSpot CRM", "Zapier" tai "Analytics pipeline".
Vaihe 5: Liitä HTTPS-URL-osoite. URL-osoitteen on käytettävä HTTPS:ää. Jos käytät Zapieria tai Makea, liitä niiden antama webhookin URL-osoite.
Vaihe 6: Tarkista tapahtumat, jotka haluat vastaanottaa. Voit valita minkä tahansa yhdistelmän.
Vaihe 7: Napsauta Create.
Cowlendar näyttää allekirjoitussalaisuuden alkaen whsec_. Kopioi se välittömästi ja säilytä se turvallisesti. Tämä salaisuus näytetään vain kerran, ja tarvitset sitä saapuvien webhook-pyyntöjen vahvistamiseen palvelimellasi.
Voit muokata mitä tahansa päätepistettä myöhemmin muuttaaksesi URL-osoitetta tai ottaaksesi käyttöön tai poistaaksesi tietyt tapahtumat:
8 webhook-tapahtumaa
booking.created käynnistyy, kun uusi varaus luodaan mistä tahansa lähteestä: myymälän widgetistä, hallintapaneelista, myyntipisteestä tai julkisesta sovellusliittymästä. booking.confirmed käynnistyy, kun järjestelmänvalvoja vahvistaa manuaalisesti odottavan varauksen. booking.declined syttyy, kun odottava varaus hylätään. booking.canceled syttyy, kun asiakas tai järjestelmänvalvoja peruuttaa varauksen. booking.rescheduled syttyy, kun varauksen päivämäärä tai määrätyt tiimin jäsenet muuttuvat. booking.attendance_changed käynnistyy, kun läsnäolotila muuttuu, esimerkiksi "varatusta" tilasta "valmis" tai kun se on merkitty "ei-show". subscription.created käynnistyy, kun uusi toistuva tilaus luodaan. subscription.billing_failed käynnistyy, kun tilauksen laskutusyritys epäonnistuu. Kolmen peräkkäisen virheen jälkeen tilaussopimus puretaan automaattisesti Shopify:ssä ja paikallinen tila muuttuu canceled:ksi.
Miltä webhook-hyötykuorma näyttää
Jokainen webhook-toimitus on HTTP POST, jossa on JSON-runko. Tässä on täydellinen booking.created-esimerkki:
{
"id": "evt_2b86f80a-1c3d-4e5f-9a8b-7c6d5e4f3a2b",
"type": "booking.created",
"created_at": "2026-05-20T09:15:00.000Z",
"shop_domain": "yourshop.myshopify.com",
"data": {
"id": "abc123def456ghi789jkl012",
"booking_str": "COW-1234",
"service": {
"id": "6789abcdef0123456789abcd",
"title": "Haircut",
"type": "classic-checkout"
},
"start_date": "2026-05-27T14:00:00.000Z",
"end_date": "2026-05-27T14:30:00.000Z",
"timezone": "Europe/Paris",
"customer": {
"name": "Jane Smith",
"email": "[email protected]",
"phone": "+33612345678",
"locale": "en"
},
"form_data": {},
"quantity": 1,
"unit_quantity": 1,
"quantity_details": [],
"price": { "amount": 35, "currency": "EUR" },
"confirmation_status": "confirmed",
"attendance": "booked",
"financial_status": null,
"is_canceled": false,
"teammates": [
{
"id": "aaa111bbb222ccc333ddd444",
"firstname": "Marie",
"lastname": "Dupont"
}
],
"order_id": null,
"subscription_id": null,
"created_at": "2026-05-20T09:15:00.000Z",
"updated_at": "2026-05-20T09:15:00.000Z"
}
}
data-kenttä sisältää koko varaus- tai tilausobjektin täsmälleen samassa rakenteessa kuin API-vastaus.
subscription.billing_failed-tapahtumissa hyötykuorma sisältää ylimääräisen previous-objektin failure_count:n kanssa ennen nykyistä yritystä, joten voit seurata eskalaatiota esimerkiksi lähettämällä kiireellisen sähköpostin toisen epäonnistumisen jälkeen.
Pyydä otsikot jokaisen webhook-toimituksen yhteydessä
X-Cowlendar-Event-Id on tapahtuman yksilöllinen tunnus. Cowlendar käyttää samaa tunnusta uudelleen yrittäessään epäonnistunutta toimitusta. Käytä sitä kopioiden poistamiseen puolellasi.
X-Cowlendar-Event-Type on tapahtumatyypin merkkijono, esimerkiksi booking.created.
X-Cowlendar-Timestamp on Unix-aikaleima sekunneissa, kun Cowlendar allekirjoitti pyynnön.
X-Cowlendar-Signature on HMAC-SHA256-allekirjoitus muodossa t=<timestamp>,v1=<hex>.
Vahvista webhook-allekirjoitus
Jokainen webhook-pyyntö allekirjoitetaan, jotta voit varmistaa, että se todella tuli Cowlendar:ltä eikä sitä ole peukaloitu. Allekirjoitus lasketaan muodossa HMAC-SHA256(secret, timestamp + "." + raw_body) käyttämällä päätepisteesi allekirjoitussalaisuutta.
Sinun tulee myös hylätä pyynnöt, joiden aikaleima on yli 5 minuuttia, jotta voit estää uusintahyökkäykset.
Node.js (Express):
import crypto from "crypto";
import express from "express";
const app = express();
app.post(
"/webhooks/cowlendar",
express.raw({ type: "application/json" }),
(req, res) => {
const sigHeader =
req.header("X-Cowlendar-Signature") || "";
const timestamp =
req.header("X-Cowlendar-Timestamp") || "";
const rawBody = req.body.toString("utf8");
// Reject requests older than 5 minutes
if (
Math.abs(Date.now() / 1000 - parseInt(timestamp, 10))
> 300
) {
return res.status(400).send("Timestamp too old");
}
const expected = crypto
.createHmac(
"sha256",
process.env.COWLENDAR_WEBHOOK_SECRET
)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
const received = sigHeader
.split(",")
.find((p) => p.startsWith("v1="))
?.slice(3);
if (
!received ||
!crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(received)
)
) {
return res.status(401).send("Invalid signature");
}
const event = JSON.parse(rawBody);
// Short-circuit test pings
if (event.type === "webhook.ping") {
return res.status(200).send("pong");
}
// Handle real events here
res.status(200).send("ok");
}
);
Python (pullo):
import hmac, hashlib, os, time, json
from flask import Flask, request
app = Flask(__name__)
@app.post("/webhooks/cowlendar")
def cowlendar_webhook():
sig_header = request.headers.get(
"X-Cowlendar-Signature", ""
)
timestamp = request.headers.get(
"X-Cowlendar-Timestamp", ""
)
raw_body = request.get_data(as_text=True)
# Reject requests older than 5 minutes
if abs(time.time() - int(timestamp)) > 300:
return "Timestamp too old", 400
expected = hmac.new(
os.environ["COWLENDAR_WEBHOOK_SECRET"].encode(),
f"{timestamp}.{raw_body}".encode(),
hashlib.sha256,
).hexdigest()
received = next(
(p[3:] for p in sig_header.split(",")
if p.startswith("v1=")),
None,
)
if not received or not hmac.compare_digest(
expected, received
):
return "Invalid signature", 401
event = json.loads(raw_body)
if event["type"] == "webhook.ping":
return "pong", 200
# Handle real events here
return "ok", 200
PHP:
<?php
$secret = getenv("COWLENDAR_WEBHOOK_SECRET");
$rawBody = file_get_contents("php://input");
$sigHeader = $_SERVER["HTTP_X_COWLENDAR_SIGNATURE"] ?? "";
$timestamp = $_SERVER["HTTP_X_COWLENDAR_TIMESTAMP"] ?? "";
// Reject requests older than 5 minutes
if (abs(time() - (int)$timestamp) > 300) {
http_response_code(400);
exit("Timestamp too old");
}
$expected = hash_hmac(
"sha256",
$timestamp . "." . $rawBody,
$secret
);
$received = null;
foreach (explode(",", $sigHeader) as $part) {
if (str_starts_with($part, "v1=")) {
$received = substr($part, 3);
break;
}
}
if (!$received || !hash_equals($expected, $received)) {
http_response_code(401);
exit("Invalid signature");
}
$event = json_decode($rawBody, true);
if ($event["type"] === "webhook.ping") {
http_response_code(200);
exit("pong");
}
// Handle real events here
http_response_code(200);
echo "ok";
Testaa webhookiasi ennen lähetystä
Jokaisessa webhook-päätepisteessä on Test -painike järjestelmänvalvojassa. Sen napsauttaminen lähettää synteettisen webhook.ping-tapahtuman URL-osoitteeseesi. Tämä tapahtuma käyttää samaa allekirjoitus-, otsikko- ja uudelleenyrityskäyttäytymistä kuin todelliset tapahtumat, mutta vaarattomalla testihyötykuormalla:
{
"id": "evt_2b86f80a...",
"type": "webhook.ping",
"created_at": "2026-05-13T14:57:57.704Z",
"shop_domain": "yourshop.myshopify.com",
"data": {
"message": "This is a test event from Cowlendar. If you can read this, your endpoint is reachable."
}
}
Käytä tätä vahvistaaksesi, että Cowlendar voi saavuttaa URL-osoitteesi, että DNS-, HTTPS- ja palomuuriasetukset toimivat, ja vahvistaaksesi HMAC-allekirjoituksen vahvistuskoodisi luomatta todellista varausta. Todellinen varaus lähettäisi sähköpostiviestejä asiakkaalle, luo kalenteritapahtumia ja mahdollisesti laukaisi Shopify-tilauksen.
Kun olet napsauttanut Testaa, tarkista See deliveries -painike nähdäksesi päätepisteesi palauttaman HTTP-tilakoodin. Vihreä 200 tarkoittaa, että kaikki toimii.
Yritä toimintaa uudelleen ja poista automaattinen käytöstä
Jos päätepiste palauttaa 5xx-virheen, 429:n tai verkon aikakatkaisun, Cowlendar yrittää uudelleen tämän aikataulun mukaisesti:
1 minuutin kuluttua, 5 minuutin kuluttua, 25 minuutin kuluttua, 2 tunnin kuluttua, 10 tunnin kuluttua, 50 tunnin kuluttua. Tämä on yhteensä 6 yritystä, jotka kattavat noin 3 päivää.
Noin 20 peräkkäisen virheen jälkeen kaikissa tapahtumissa päätepiste poistetaan automaattisesti käytöstä ja Cowlendar lähettää sähköpostia kaupan omistajalle. Voit ottaa päätepisteen uudelleen käyttöön Settings > Webhooks:stä, kun palvelimesi on jälleen online-tilassa.
Samaa X-Cowlendar-Event-Id:ää käytetään uudelleen yritettäessä. Tallenna aina käsitellyt tapahtumatunnukset ja ohita kaksoiskappaleet.
Mikä tahansa 2xx-vastaus lasketaan onnistuneeksi. Sinun ei tarvitse palauttaa tiettyä runko- tai sisältötyyppiä.
Webhookin parhaat käytännöt
Vastaa 10 sekunnissa. Jos käsittelijäsi joutuu tekemään raskasta työtä, kuten kutsumaan toista APIa, kirjoittamaan tietokantaan tai suorittamaan monimutkaisen toiminnon, tee se asynkronisesti. Hyväksy webhook välittömästi 200:llä ja käsittele se sitten taustatyössä tai jonossa. Poista kopio käyttämällä tapahtumatunnusta. Tallenna jokainen käsittelemäsi X-Cowlendar-Event-Id. Jos saat saman tunnuksen uudelleen, ohita se. Cowlendar yrittää uudelleen samalla tunnuksella epäonnistuessa. Käytä vakioaikavertailua allekirjoituksiin. crypto.timingSafeEqual Node.js:ssä, hmac.compare_digest Pythonissa ja hash_equals PHP:ssä. Säännöllinen merkkijonojen vertailu, kuten ===, on alttiina ajoitushyökkäyksille. Älä yritä uudelleen puoleltasi. Cowlendar käsittelee uudelleenyritykset automaattisesti. Jos palvelimellasi oli tilapäinen ongelma, palauta 5xx ja Cowlendar palaa uudelleenyritysten aikataulunsa mukaisesti. Käsittele webhook.ping nimenomaisesti. Palauta 200 välittömästi ping-tapahtumia varten. Näin voit käyttää Testaa-painiketta käynnistämättä liiketoimintalogiikkaasi.
Nykyiset rajoitukset
API kautta luodut varaukset ovat manuaalisia varauksia. Ne eivät luo Shopify-tilausta. Jos palvelusi käyttää normaalisti Shopify checkoutia, API ohittaa sen. Vahvistussähköpostit, tekstiviestit ja kalenterin synkronointi toimivat edelleen normaalisti. Ei vielä saatavuuden päätepistettä. Nykyisen API:n avulla voit lukea palveluita ja varauksia sekä luoda varauksia. Se ei paljasta käytettävissä olevia aikavälejä. Voit tarkistaa, onko aikaväli käytettävissä, yrittämällä luoda varaus ja käsittelemällä 422-vastauksen, jos aika on varattu. Käytettävyyspäätepiste voidaan lisätä tulevassa päivityksessä. Ei vielä päivitettyjä tai poistavia päätepisteitä. Voit luoda ja lukea varauksia, mutta et voi päivittää, ajoittaa uudelleen tai peruuttaa niitä API:n kautta. Hallitse näitä toimintoja toistaiseksi Cowlendar-järjestelmänvalvojan kautta. Sovelletaan hintarajoituksia. Jos lähetät liian monta pyyntöä lyhyessä ikkunassa, API palauttaa 429. Lisää joukkotoimintoihin, kuten kaikkien varausten vientiin, lyhyt viive sivuttujen pyyntöjen väliin, esimerkiksi 200–500 ms. Webhookin salaisuudet näytetään vain kerran. Jos kadotat allekirjoitussalaisuuden, poista päätepiste ja luo uusi saadaksesi uuden salaisuuden. Webhookit vaativat HTTPS:n. HTTP-päätepisteitä ei hyväksytä.
FAQ
Voinko käyttää Cowlendar APIa Zapierin tai Maken kanssa kirjoittamatta koodia?
Kyllä. Webhookeille, jotka vastaanottavat tapahtumia Cowlendar:stä, luo "Custom Webhook"-triggeri Zapierissa tai Makessa, kopioi niiden antama URL-osoite ja lisää se päätepisteeksi Cowlendar Settings > Webhooks:ssä. Jokainen varaustapahtuma laukaisee automatisointisi. Jos käytät sovellusliittymää ja lähetät pyyntöjä Cowlendar:lle, käytä Zapierin tai Maken "HTTP Request"-toimintoa kutsuaksesi mitä tahansa Cowlendar API-päätepistettä siirtotietunnuksellasi.
Lähettävätkö API:n kautta tehdyt varaukset sähköpostiviestejä asiakkaille?
Kyllä. API:n luomia varauksia käsitellään täsmälleen kuten manuaalisia varauksia. Vahvistussähköpostit, tekstiviesti-ilmoitukset ja kalenterin synkronointi käynnistyvät automaattisesti, aivan kuten hallintapaneelin kautta tehdyissä varauksissa.
Mitä tapahtuu, jos webhook-päätepisteeni laskee?
Cowlendar yrittää epäonnistuneita toimituksia uudelleen 6 kertaa noin 3 päivän aikana. Noin 20 peräkkäisen virheen jälkeen päätepiste poistetaan automaattisesti käytöstä ja saat sähköpostin. Ota se uudelleen käyttöön Settings > Webhooks:stä, kun palvelimesi on palannut.
Voiko minulla olla useita webhook-päätepisteitä?
Kyllä. Luo niin monta kuin tarvitset, jokaisella eri tapahtumavalinnat ja URL-osoitteet. Esimerkiksi yksi päätepiste CRM:llesi, joka kuuntelee booking.created- ja booking.canceled-tiedostoja, ja toinen analytics pipeline-laitteellesi, joka kuuntelee kaikkia tapahtumia.
Voinko peruuttaa API-tunnuksen? Kyllä. Siirry kohtaan Settings > Public API ja napsauta Revoke -painiketta. Tunnus lakkaa toimimasta välittömästi. Onko siellä hiekkalaatikko tai lavastusympäristö?
Ei tällä hetkellä. Käytä webhook.ping Test -painiketta vahvistaaksesi webhook-asetukset luomatta todellisia varauksia. API-testausta varten suosittelemme luomaan Cowlendar-järjestelmänvalvojaan testipalvelun, jota käytät vain kehitykseen.
Missä koko API-viite on?
Interaktiivinen API-dokumentaatio, jossa on kaikki skeemat, parametrit ja vastausesimerkit, on osoitteessa https://app.cowlendar.com/public-api/docs