> ## Documentation Index
> Fetch the complete documentation index at: https://storekit.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Log esaurimenti e riepilogo mattutino

> Registrare ogni piatto esaurito con motivo e origine da item.out_of_stock, classificare gli ultimi 30 giorni e inviare un digest Slack ogni mattina.

Ogni volta che un piatto esce di stock — sospeso dal team, esaurito attraverso l'inventario o disattivato dalla cassa — storekit invia un evento. Questa recipe li registra, ti mostra i pattern (quali piatti, quali giorni, a che ora) e pubblica un riepilogo su Slack ogni mattina così il responsabile acquisti e lo chef iniziano la giornata sapendo cosa è finito.

> [!TIP]
>
> La dashboard ha già un report degli snooze sotto **Reports** (vedi [Report degli snooze](/docs/it/guides/menu/availability-snoozing#snooze-reporting)). Costruisci questa recipe quando vuoi vedere nello stesso elenco anche gli esaurimenti da inventario e le modifiche dalla cassa, o vuoi che il riepilogo venga spinto su Slack invece che consultato.

## Come funziona

1. storekit invia `item.out_of_stock` alla tua app ogni volta che un articolo diventa non disponibile.
2. La tua app registra l'articolo, l'ora, il motivo e chi lo ha causato.
3. Un job schedulato gira a un orario che scegli ogni mattina e pubblica l'elenco di ieri, più una tabella continua "più esauriti questo mese", su Slack.

## Cosa ti serve

* I webhook abilitati sul tuo piano storekit (**Settings** → **Developers**).
* Un account [Replit](https://replit.com). Questa recipe ha bisogno di un URL pubblico che resti attivo, di un database e di uno scheduler per il job mattutino, che Replit fornisce tutti in un solo posto.
* Un URL di incoming webhook Slack per il canale che deve ricevere il riepilogo.

## Step 1: costruisci l'app

Incolla nel builder l'intero blocco in un unico messaggio.

[![Open in Replit](https://replit.com/badge?caption=Open%20in%20Replit)](https://replit.com/?stack=Build\&prompt=JIAg7ghgdgLiEgM4FsIBs3gKYCN4Ad8QYALCOAayy30XhDQHsBzERgMxCwDcsAnAJ4hkWKAFcQASxhZkxMnGaMsdRmLgckMRgGMK8OMiF8VMCGL7QYAGnhQAJklH26CRCUZ849yc1PFGEABlNAg9Ll5BYU8oSShmADotTywKaWIsDDpSLAIiCBw1OERtPQBaIrocITBcD0YKJIAVElyIQmExEpAoHn4GRkQ2qAjRGx6+vhAdNVh5XMQIEVG5mDBJHSxbaEdeyOEIKmSTNLhIaQSAKEuAITFJNEd09dJ6e3ICiCGkQJyB1kQFm4kl4dBMJQgXkQ2xG6EgAkQFRG+DEODQGxAAAkmk0AApBEAAVQASgAZGGONw6Vr2MRoLCOABWjDw7E88xAPj8JSulwAwgB5AByTQAogANJogACCNwFhKlQSaAuJooA0sAmtdQHwxLCQB5EPhpOhpEIcF04ipVCMSilTiAABR2k4XGbIACUMLYUHRvTYfHs-DirB2IHwEAEIlgdHwoRgbL4ckTIHBZgsVmh0wg7AAl64HCAcJDEEkXal0jpoD1GDBJOwhEY2GBYR0CkV5CHsgoDe18KIpCMm+Wi0Ihg4Q9gcPUKKXrpjGGBjhWznVGA06GBPBQAFyXMogUVhEgrOCSAtYnG4kC4gVK8DSE8IABSQWFRcY9iE2noJNJIB1LBmHPGQpjiDlywdd53EKSF7CuA8WlyQov17bsFjIfsQAAbxAAAiPpYDwnd8IAHkIuAYAEfsAD48NsPD3jMYicJABJ2JAABfLjmi3LgAA9NnwOtGCgRASL+elmDCIRPCDPgEh0ExyAZU8nXsQIoFrEAulyaQAG4dO+OT+EU5SZHg7gACYPScBx0KLSFchMqYWUZLAdHGMM-hchITHYPV4KUrAVMcAB6AN5L8rAAocBJAR0TYGVUiLfP8wKEnYCAHlUijY3USL+FsHQum0EQ+FsXhxGGRx0sLXp+MowIKMHEoQscTQ4kQSQg05D4EJAYksAARzEUxXBMJBfF6RwXhPIJgX4pJRUiYwRrG7oqz4PhJBUDlWggeS6EQRayh62wTskfiyjrEQIWQfJC0u67uuYKByAsLAkgANWDBt5jkOaOQ4dgNkkdAQAAA2eyGGEkHBLCiFMBDUKZQniMQID8WxLXieghmCuBQHWDBwz4RhgV68Dq1EYFyagaM4G4SFwbRXIqwwVSlRVdVNQAfQAdVFG5MQFAU1T5oJRT5VUmiSIb3M8uwBFISdSHIEAsoeOhInrDZyEkUSH1ebE8RAAAWAAGS2BoAWSEZx8EYOJDFK1MVCdwsgYQKz+P4rQPs3R9wIARgAVicGZ7KSIIIF4DkWp-P4mM+b5Qb4EpbHBT3HCs63bByEYNI5Lc+H0dhybkP5Fl4RwZnwAQBoFKBNgA3t4+z0Sg1z-PlwdEnMC04pnHkDWWqx7KoAu35WnAbdOm6Iei1yJgShIkcQupNTvYDmAuidfsJ3iWwNN6WwtfpexbLDUS0EbSF9HSU+2nYUCS-nshXE8zGMDHMREuoN3JIzcA5eDEI9Dq+pbpFXDBsfQ4DlaqzxiUB4mBD4+DxuyC+qkwwmBgFEC4IAhSTE5DPXIpd9C3yEOBEQyBPBCBzG-TuR9Ej7hAEhJASxcgtSrCMXQVZuqiXQHfZenJMggn4KpOhk11Z8Jbl9Ik3xq6nR6gadq-Qvgcj1JIUauQqBCBTNXOOuUqowBIggEw-YNaaBpqY+AaBlKoRrqpc8Ug3opHsLYMACgSHSGOmYPec4DzSigEICMfgAxcAcE7F2ZNaweQsqOegEZECIFLo4ZAbscALH4LXNg+xTb4h9HfQyJgfAmCVuydK3w4yT0vHiO2oksAGN2o8OgjptBmDQAXSQ+AT7iNWgAMWoCfc8Mw9QwCaLWdAthpCyDJhsLY0QfCg36PgHamxr6TRdkBfgdAaFxHZNomA4kQBWTDtbYQIUxIgAAMXnISNbAaLkmjUT0jaZynAAAiAz+ACFsLiOB4DbDACgEEbQJhbB8gsDgbqQYoUqR2vEH56JVoItAiGQFegEHshuKgiMjc2FmDZlIG0Ij1kqDGJrdkcQygjhcogQyQZUV-OlPYew4ICyOGNHoQk+AmiSGWFQ6lUxmUSKiAypIAtWgjByEIYuS8+wiL+Po0lbBkDSAstPYg5l6AatSZOVVRjliaPEBgJIQ89phjmcgRAABtAAugkS12YRjZJ6HSTA7JZDCUbtMUqjByqKUDRGUJQouF2DrgGoNzMYBCjEMgbJUw+whVcr6GoMqkDgLjLteC1xRT8SWHGZygZTLBVCgkay4ZIxMEOnuS42FLggHwhRFieFfLlospWqy9Em34RTixRtzbm14R6m2uSfMCg6BDlZAAzL24d+EZhBjbdKEONwe3WD7SOr47QWL4LGluxdeFOnoBYuc-O278J1nwOei5R7h2MV+YIYZWBz0AE530PpHT4RA4zYBTK6SxS2378IvLeW2lF4qBALsfTyigfKBUiDbXnKy5syiWxDmUcOTQQ6Wx3ObMOO5rYAC1YMjupNAXoaA21CxuOR-CTt42Jv4CxM13Sr14U7QyaUMAUOWzQxhrDOG8M7lnfh0jDGn0ssEEht9JE8KofQ5h7DYdcMh2IxJy2ZHQN4UtYgNtxJJwaU8NkjAUmSp2nKoOq9I704lHDchhTz5GAkCgAxkdoQHNcMg8oDzLbUAPDbcyNzAABLAhaHr0mDcgfzeF8AeF6G2gA1Obc2M7Z2EYAGwAHYAAc764uoDLlgOs8Q+SiXHHxiSuosBXs4rpm1BmSJ2tszhNrI73pOfwrbSEzBWg7TMDeSQAAvEbEB-MjvWS7Rz8met9YGyaSbjGNlzZnZexdx7RpWDNCxEOoHj1xjEGxz1B24ODGAPYE7GAzsjrMPxYkKlz0gY6-hS112OObcfXQlZu0M4sVa19xduE9M+YUwW-BCBqTUCGPRFbM2wf4T5K0SlcP4urb2-e-C23YC7ZIvtxjaBjskXYwxJ2iBLsfYYvdx7MhntcVew6trnEr0Ot01VMaNmvujqu-jud5szug+63he2g1TDmEsERQXiAifMDbUYMoaYJdWDi4dDl1oudA7wiUEwpWQ5toyyAXr4FwXLe1-g6gMAe0KbNzoPH+FSRd1Emb8nMAKsroUwLEO0oQDe+lLb2Y+CYMKcJGqAPD1oACFm220XQ0IQZjmKSGAV3btLvXIGOIKlmusTwvGaQYgPcgDDiHBIFycsC-wkweI+fC8YYSDO-LDOvss8XQ1zjYrVpsvV6kzXx6deW-1wp7LIABSHBlLwOL-fSvW-woM+MZy4t26om2x3DhneC9d+7ubeFRQhxAFl6UQpF+B8EG20PcX9NU7a1x9PGCs+DsrwbPehfi+l-DmHBiVfgLP7m3Xy2OWrIrIm9h0W8GcWdLgOEApSZ0RuhNBE43kuVq0BBa0XA1UNYSAYAYBaAdwwowpII3RA0woNIdBEAiC+gmB+wM4wpahpx1xZxqC1wGgyg8prgmhMRRRDxvpRQRR2FMRgACRpRcRrxCQpYggSIbUEgig+YOA+Y7Q9BtR3EZFZ4XIBIi16R4BCheBDJVZXAOhhUtorVCgCoJCpCZC5CKAvESANgTwmANw4YjgdD60h0W1TE20TD1BpD2BZDSgKBYNGIPhe98IOc5sQcx0+dMsGIutt9Y9xcE8+MuJGsZBYsSJQjeci9cs8tIjEcRcFtgwhtAUxsJsycic21cRSRCQMNMM0dydKcFNyc+YbU+ZzZN18JEAKBid8Igg1QKjbZpRiQABxSo-XBIzjZSRAZ3BTRALSRgEbBkKTcYiwTYeXaAH+KTIMMwbWB-bXaY2Y0UBwfjQTFTETPLTTTTMjYAlncAg8MYo2VxJpNgdgdeHY1SDpH1TwFmERKw9lAcaoAOdgdgL0QcUxehPmIMYtRJZ0RgR4NgAqUgcmMQfrIEsYehaYQPRAQE39AoS+J0NJaQaHDqf4j0AaBYvgVuO4-0DgEiVAcQCGSEkQe48CZOL4EgWCQMQElQx0KHaNfoFQ3SRwSSL4DQXoDE59BJWwdEfrE5fsBkWwEbIRbpcMQYWQgQFuA+LoGkTWSuegOsUmGlWAICSwESKAIkthdY7KNAUsKY9cXYwsck8lcEKlFMG420Z4ykQsXhURUnK5aAScK0mYlxBwGKOIOZO+AaI7WwGot0xwNoiQD091djAaJCbZOgLSfCYscIcCcwvCU8ZoWePsd2GYQMTcTNJBZgTcKlIoQySsKjbSCgLSJcbxAcOVbMZYdMxoa4AWTEaUKUZUEAG4QkYAUkL5a4EvG8O8KUBg2gjcPAiFFcEAQAFAIQBdZ-o-gForopo3oPpJogYfJ-iwYIZno4YEZIQGFCxuZVQNQmhBZhZRZxZJZpZZZ4BpIupKJZ5LAlwTBdFugUIBBDIrZLYfRNZzTPoY5jEE47FcFSsLARg84ALBURAfAVJQyAJFDhgxwVFKQHF2oxxjF4IsQdh1D3CYBPDvDdAKBDJnFI14A9B6zL4IlI82Acgph4CsILRvBNJawrC8YgYLhLgrIkgfcmBWBiV1C5oSIKksAJF+TBVchnRZyiQmg+RRkjRQhqERgmhgBbZRQSNhRRRATgieguFZkkjDKRBjL5lzpwwicLp2is4Qpxip4fhFilk-SbS8KhpCz+TZ4KIABybIGS+AByaBEuRg-QSEHaWuK4WdJIfo0UCchcuJGQTyVSX4wpRybqHQeAdQE8IGaUL5W2YAIUPmXEaUIIIIAWFUL5XM3XTseIG0H0XIcJLAPcYdCAJIPCAATVMH4HeFPP5M-EjBYgQBgI0E4HMIqHUGOjiFbmrjMC8AeJAAEG6sDEjEHHYU0u0t0tsF6FqG6Hs3GHcEXDVhkvMuQDsq+CNjDBJLJORFCHAnSXaTwiCFdKSQhH+J0lx0wBDhOOtjRyCChI6lhJIHhMRLiGBKiEYQ0T4VLT4D+peHxIeM4ArkDRABI3lLwhNOHRwHattkGGKABphPGC8zgHEz6gRBYia1TGgCoEcF+PEBY1cjGp8ImpOS8UfA5H-TgG8lnjoU2kDToRGA8AsAWt6qkDgEwkPjnGHR0CSEGQeFAjoBTAMsdHrDbjIHjmkVyFkQasBOdKooQCYlyEl2xn1pAC+UXF9EYEOhAD5CCG+iLHUG0FlR7AiydihHAB8X2FcVBjQFAlUh3NnhmCJ2QBuWRrkBiTmH4suHNgEr6geHlV8H8Fd1Uh-BCDCH0GBAQCCFJGlD5Aljo1vIlj-AMDNuAFiqVD5g0q0qdExExB3FtltjWqrs2qFFFH6SyjpDgH-zE0tiJJttEhkFgFmRGDTvCGQDLnsBbBaubQACp-roSOwlq2oVqhBFzSIDKoiaJbBSJDaaIZ7t1m4V4rRwx+gbVh7iAAqXIFMQ5zYdw85m1es+B+s8iEACjxsErxiF6CoVaoBwaBAPRsz2Q8JvriMI5ggQo+yvg6BFzXKUqxwzB3qJkHgzkNNfqYr4SiBfiDLVamL3loglDqwmkrhh0kJ9Q0Rqa4Z-Qww8IZ7cbuhP7AbXzXEBbSAZ7sy2QMBFw4GORtAiBQZ45KagZOapbm1gBOAh4uKAQCbF7lreqIy8b8IhROLfTpGCol7QJeqEhsyYGdS0E8btVQA6zFwOR8zXFTReBiHm1cQFHk5E7YD5ET7RVVrCIpBOA-h8ylcoRxKPI5IORDaFqBTuguR-AqsqK2jelXGxa0J7FHFzRqBbRHT2R1ZvAVIrgw5Y6nqR5gnF5Fxsy2KnbAK-gmqRUMgUFj4PbrDFSSgHJsm4BkZZHVqTBpJAx6RUkFrGymKonIBXAsLDoxwxgrgssYq4qQAwoDpfaTxkn3Y94+AblYKqKQcGh91asuIqKJHJxMghheRCRvhm6dLW6SnJh5VVqjCHATyqLf1aklrpKRAkhzaaxFANpXAxEO7fbxDOA9ndK1U9QhhxhqktbAgIR5qwwhL6AdB6RIQrlUksYvprgvlRRBlCrNRgB3wBRBkzbdLrgDw7UQAHUZQNyZoxbZBJCPCzCfC1IU0Sw1rJIWBjYuL8YfHCxubuFolnY5g8FoLVJYKBocW8WOFFhlgWoO9JF+T1hW5uMPlUxFweXcX8XixozpotyjaoLZm6B-yqKhKUzlH4gZW+XvLIti0kCUCNCKYMJFxXA6Acin7Ft8jRt36YGXrfi3rOAkGvqfrLY8JdX2FZ5amqmTkS6vky7RQK7m61ntIJ5GSew5HBxwWC9JxIbk13YgWYAvXMnCxfX6zszXdshAhR7H5kAELwYZBQy2FeXvXchbb7aNIWxjXGBJa1q3AKVDp3BLc6WGqpWlxKCKXCw-gg6E0bkRqGQvW485qythK8yOhV49p1mdWOyuyeyBQQB+jgAuCjcODOzuCQAOr5QZRVQMXW6RzczGrUR0RMqaCZwiQyQnRAAyAknJnFIPwJgGvh7dnmKb-CuH4vLaiTplEkZiXJZixL2h-F+adHPN5ivILrFglilhljitsDyoKqKpKrKoquJC+VsGztzvzpvKg75j-FsE+dbtsEDfLqvObufdmgGwBacFfPmSNh0KsvIETGQCiqSAqygHTlQCNNHlo7yADgRB0iIDQwNFRmedFu5o1mrnxLpFUmZDwF1BuUbJGC0h-OiaKZhbYEPiuCAA\&referrer=docs.storekit.com)

[![](https://mintcdn.com/storekit/IGeB_84apyho3Z6U/images/logos/lovable.svg?fit=max\&auto=format\&n=IGeB_84apyho3Z6U\&q=85\&s=cc21d11769d5e6b686fed56390a88f5e) Build with Lovable](https://lovable.dev/#prompt=I%20want%20a%20small%20web%20app%20that%20keeps%20a%20log%20of%20every%20menu%20item%20that%20goes%20out%20of%20stock%20at%20my%20restaurant%2C%20and%20sends%20a%20short%20digest%20to%20Slack%20every%20morning.%20storekit%20tells%20the%20app%20about%20stock-outs%20by%20webhook.%20The%20app%20must%20never%20lose%20an%20event%2C%20never%20count%20the%20same%20event%20twice%2C%20and%20never%20make%20storekit%20wait.%0A%0ABuild%20it%20with%20a%20database%20so%20the%20log%20survives%20restarts%2C%20an%20always-on%20public%20HTTPS%20URL%2C%20and%20a%20scheduled%20job%20for%20the%20digest.%0A%0ACONTEXT%20ABOUT%20STOREKIT%0A%0AI%20run%20a%20hospitality%20business%20on%20storekit%20\(storekit.com\)%2C%20an%20online%20ordering%20and%20payments%20platform%20for%20restaurants%2C%20caf%C3%A9s%20and%20bars.%20storekit%20can%20notify%20my%20own%20app%20about%20things%20that%20happen%20in%20my%20store%20by%20sending%20webhooks.%0A%0AHow%20storekit%20webhooks%20work%3A%0A-%20Each%20event%20is%20an%20HTTP%20POST%20with%20a%20JSON%20body%20to%20a%20URL%20I%20register%20in%20the%20storekit%20dashboard.%0A-%20The%20body%20has%20the%20shape%20%7B%20%22event%22%3A%20%22%3Cevent%20type%3E%22%2C%20%22data%22%3A%20%7B%20...%20%7D%20%7D.%20Two%20exceptions%3A%20the%20legacy%20order.created%20event%20\(do%20not%20use%20it%3B%20use%20order.created.v2\)%20sends%20the%20bare%20order%20object%2C%20and%20the%20order.refund.created%20%2F%20order.refund.succeeded%20%2F%20order.refund.failed%20events%20put%20order%2C%20customer%2C%20venue%20and%20refund%20next%20to%20event%20instead%20of%20inside%20data.%0A-%20Requests%20are%20signed%20with%20Svix.%20Every%20request%20carries%20the%20headers%20svix-id%2C%20svix-timestamp%20and%20svix-signature.%20Verify%20them%20with%20the%20official%20%60svix%60%20library%20for%20your%20language%2C%20using%20a%20secret%20I%20will%20provide%20in%20an%20environment%20variable%20called%20STOREKIT_WEBHOOK_SECRET.%20Reject%20anything%20that%20fails%20verification%20with%20HTTP%20400.%0A-%20My%20endpoint%20must%20respond%20with%20a%202xx%20status%20within%2015%20seconds.%20Save%20the%20event%20to%20the%20database%20first%2C%20respond%20200%2C%20then%20do%20the%20work%20from%20the%20saved%20copy.%0A-%20Once%20I%20have%20responded%20200%2C%20storekit%20will%20not%20send%20that%20event%20again%2C%20so%20the%20work%20must%20not%20be%20lost%3A%20store%20each%20event%20with%20a%20status%20\(pending%2C%20done%2C%20failed\)%20and%20only%20mark%20it%20done%20after%20the%20work%20has%20actually%20succeeded.%20On%20startup%20and%20on%20a%20timer%2C%20pick%20up%20anything%20still%20pending%20or%20failed%20and%20retry%20it.%20Never%20do%20the%20work%20only%20in%20memory%20after%20responding.%0A-%20The%20same%20event%20can%20occasionally%20be%20delivered%20more%20than%20once.%20Use%20the%20svix-id%20header%20as%20the%20unique%20key%20for%20the%20saved%20event%3A%20a%20repeat%20of%20an%20event%20already%20saved%20is%20ignored%2C%20whatever%20its%20status.%0A-%20Any%20page%20or%20endpoint%20protected%20by%20a%20password%20must%20be%20served%20over%20HTTPS%20only%3B%20redirect%20or%20refuse%20plain%20HTTP.%0A-%20Money%20fields%20\(total%2C%20tip%2C%20deliveryFee%2C%20discountTotal%2C%20item%20price%2C%20modifier%20price\)%20are%20integers%20in%20minor%20units%3A%202500%20means%20%C2%A325.00.%0A-%20orderType%20is%20one%20of%20Delivery%2C%20Pickup%2C%20InStore%2C%20Curbside%2C%20CateringDelivery%2C%20CateringPickup%20or%20Billpay.%0A-%20table%20is%20only%20present%20for%20in-store%20orders%3B%20deliveryAddress%20and%20pickUpTime%20only%20for%20delivery%20orders.%20When%20they%20do%20not%20apply%20the%20key%20is%20omitted%2C%20so%20treat%20a%20missing%20key%20the%20same%20as%20null.%20notes%20and%20items%5B%5D.note%20can%20be%20null%20or%20empty.%20customer.companyName%20and%20customer.vatNumber%20appear%20only%20when%20supplied.%0A%0AExample%20order.created.v2%20payload%3A%0A%0A%7B%0A%20%20%22event%22%3A%20%22order.created.v2%22%2C%0A%20%20%22data%22%3A%20%7B%0A%20%20%20%20%22id%22%3A%20%22ord_abc123%22%2C%0A%20%20%20%20%22code%22%3A%20%22A1B2%22%2C%0A%20%20%20%20%22asap%22%3A%20true%2C%0A%20%20%20%20%22total%22%3A%202500%2C%0A%20%20%20%20%22tip%22%3A%20250%2C%0A%20%20%20%20%22deliveryFee%22%3A%20299%2C%0A%20%20%20%20%22discountTotal%22%3A%200%2C%0A%20%20%20%20%22orderType%22%3A%20%22Delivery%22%2C%0A%20%20%20%20%22pickUpTime%22%3A%20%222024-01-15T10%3A45%3A00Z%22%2C%0A%20%20%20%20%22channel%22%3A%20%22WEB%22%2C%0A%20%20%20%20%22poNumber%22%3A%20null%2C%0A%20%20%20%20%22createdAt%22%3A%20%222024-01-15T10%3A30%3A00Z%22%2C%0A%20%20%20%20%22deliveryTime%22%3A%20%222024-01-15T11%3A00%3A00Z%22%2C%0A%20%20%20%20%22notes%22%3A%20%22Ring%20doorbell%22%2C%0A%20%20%20%20%22customer%22%3A%20%7B%0A%20%20%20%20%20%20%22firstName%22%3A%20%22John%22%2C%0A%20%20%20%20%20%20%22lastName%22%3A%20%22Doe%22%2C%0A%20%20%20%20%20%20%22email%22%3A%20%22john%40example.com%22%2C%0A%20%20%20%20%20%20%22phone%22%3A%20%22%2B44123456789%22%2C%0A%20%20%20%20%20%20%22marketingConsent%22%3A%20true%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22items%22%3A%20%5B%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22name%22%3A%20%22Margherita%20Pizza%22%2C%0A%20%20%20%20%20%20%20%20%22printName%22%3A%20%22Margherita%22%2C%0A%20%20%20%20%20%20%20%20%22price%22%3A%201200%2C%0A%20%20%20%20%20%20%20%20%22quantity%22%3A%201%2C%0A%20%20%20%20%20%20%20%20%22plu%22%3A%20null%2C%0A%20%20%20%20%20%20%20%20%22posId%22%3A%20null%2C%0A%20%20%20%20%20%20%20%20%22taxRate%22%3A%2020%2C%0A%20%20%20%20%20%20%20%20%22note%22%3A%20null%2C%0A%20%20%20%20%20%20%20%20%22modifiers%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%7B%20%22name%22%3A%20%22Extra%20cheese%22%2C%20%22printName%22%3A%20%22Cheese%22%2C%20%22price%22%3A%20150%2C%20%22quantity%22%3A%201%2C%20%22plu%22%3A%20null%2C%20%22posId%22%3A%20null%2C%20%22taxRate%22%3A%2020%20%7D%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%5D%2C%0A%20%20%20%20%22venue%22%3A%20%7B%0A%20%20%20%20%20%20%22id%22%3A%201234%2C%0A%20%20%20%20%20%20%22name%22%3A%20%22My%20Restaurant%22%2C%0A%20%20%20%20%20%20%22slug%22%3A%20%22my-restaurant%22%2C%0A%20%20%20%20%20%20%22address%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22street1%22%3A%20%22123%20Main%20St%22%2C%0A%20%20%20%20%20%20%20%20%22street2%22%3A%20%22%22%2C%0A%20%20%20%20%20%20%20%20%22city%22%3A%20%22London%22%2C%0A%20%20%20%20%20%20%20%20%22postCode%22%3A%20%22W1A%201AA%22%2C%0A%20%20%20%20%20%20%20%20%22country%22%3A%20%22UK%22%2C%0A%20%20%20%20%20%20%20%20%22companyName%22%3A%20%22My%20Restaurant%20Ltd%22%2C%0A%20%20%20%20%20%20%20%20%22coordinates%22%3A%20%7B%20%22latitude%22%3A%2051.5074%2C%20%22longitude%22%3A%20-0.1278%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22deliveryAddress%22%3A%20%7B%0A%20%20%20%20%20%20%22street1%22%3A%20%22456%20Oak%20Ave%22%2C%0A%20%20%20%20%20%20%22street2%22%3A%20%22Flat%202%22%2C%0A%20%20%20%20%20%20%22city%22%3A%20%22London%22%2C%0A%20%20%20%20%20%20%22postCode%22%3A%20%22E1%206AN%22%2C%0A%20%20%20%20%20%20%22country%22%3A%20%22UK%22%2C%0A%20%20%20%20%20%20%22notes%22%3A%20null%2C%0A%20%20%20%20%20%20%22coordinates%22%3A%20%7B%20%22latitude%22%3A%2051.5155%2C%20%22longitude%22%3A%20-0.0722%20%7D%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A%0AThe%20full%20list%20of%20event%20types%20and%20payloads%20is%20at%20https%3A%2F%2Fstorekit.com%2Fdocs%2Fdevelopers%2Fwebhooks%2Fwebhook-events%0A%0ATHE%20EVENT%20THIS%20APP%20USES%3A%20item.out_of_stock%0A%0AIgnore%20the%20order%20example%20above%3B%20this%20app%20only%20cares%20about%20item.out_of_stock%2C%20which%20looks%20like%20this%3A%0A%0A%7B%0A%20%20%22event%22%3A%20%22item.out_of_stock%22%2C%0A%20%20%22data%22%3A%20%7B%0A%20%20%20%20%22venue%22%3A%20%7B%20%22id%22%3A%201234%2C%20%22name%22%3A%20%22My%20Restaurant%22%20%7D%2C%0A%20%20%20%20%22item%22%3A%20%7B%20%22id%22%3A%205678%2C%20%22name%22%3A%20%22Margherita%20Pizza%22%2C%20%22plu%22%3A%20%22PLU-001%22%2C%20%22posId%22%3A%20%22pos_item_42%22%2C%20%22sku%22%3A%20%22SKU-MARG-001%22%20%7D%2C%0A%20%20%20%20%22reason%22%3A%20%22snoozed%22%2C%0A%20%20%20%20%22source%22%3A%20%22manual%22%2C%0A%20%20%20%20%22details%22%3A%20%7B%20%22snoozeEnd%22%3A%20%222024-01-15T18%3A00%3A00Z%22%20%7D%0A%20%20%7D%0A%7D%0A%0A-%20reason%20is%20one%20of%3A%20snoozed%20\(temporarily%20hidden%20by%20staff\)%2C%20inventory_depleted%20\(sold%20out%20through%20inventory%20counts\)%2C%20disabled%20\(switched%20off\).%0A-%20source%20is%20one%20of%3A%20manual%20\(someone%20in%20the%20dashboard\)%2C%20order%20\(a%20customer%20order%20used%20the%20last%20one\)%2C%20deliverect%2C%20lightspeed%2C%20zonal%2C%20pos_sync%20\(pushed%20from%20a%20till%20or%20integration\).%0A-%20details.snoozeEnd%20is%20only%20present%20for%20reason%20snoozed%20and%20can%20be%20null%2C%20meaning%20snoozed%20indefinitely.%0A-%20plu%2C%20posId%20and%20sku%20can%20be%20null.%0A-%20There%20is%20no%20%22back%20in%20stock%22%20event.%20The%20app%20records%20when%20things%20went%20out%3B%20it%20cannot%20know%20when%20they%20came%20back.%0A%0AWHAT%20TO%20BUILD%0A%0A1.%20POST%20%2Fwebhooks%2Fstorekit%20%E2%80%94%20verify%20the%20Svix%20signature%20with%20the%20official%20svix%20library%20and%20STOREKIT_WEBHOOK_SECRET%20against%20the%20raw%20request%20body%3B%20400%20on%20failure.%20Save%20the%20event%20and%20return%20200%20immediately.%20Ignore%20any%20svix-id%20already%20saved.%20Handle%20item.out_of_stock%3B%20save%20and%20acknowledge%20any%20other%20event%20type%20but%20do%20nothing%20with%20it.%0A2.%20A%20log%20table%20with%3A%20received%20time%20\(store%20UTC%2C%20display%20in%20TIMEZONE\)%2C%20venue%20name%2C%20item%20name%2C%20item%20id%2C%20plu%2C%20sku%2C%20reason%2C%20source%2C%20snoozeEnd.%20Record%20the%20event's%20time%20as%20the%20time%20the%20webhook%20arrived.%0A3.%20GET%20%2F%20%E2%80%94%20protected%20by%20HTTP%20basic%20auth%20with%20ADMIN_PASSWORD.%20Three%20things%20on%20one%20page%3A%0A%20%20%20a.%20%22Yesterday%20and%20today%22%3A%20a%20list%20of%20stock-outs%20since%20the%20start%20of%20yesterday%20in%20TIMEZONE%2C%20newest%20first%2C%20showing%20time%2C%20item%2C%20reason%20and%20source%20in%20plain%20words%20\(%22Snoozed%20by%20staff%20until%2018%3A00%22%2C%20%22Sold%20out%20through%20inventory%20after%20an%20order%22%2C%20%22Switched%20off%20from%20Zonal%22\).%0A%20%20%20b.%20%22Most%20sold%20out%2C%20last%2030%20days%22%3A%20items%20ranked%20by%20number%20of%20stock-outs%2C%20with%20the%20count%20and%20the%20most%20common%20hour%20of%20day%20it%20happens.%0A%20%20%20c.%20Filters%20for%20venue%20\(if%20I%20have%20more%20than%20one\)%2C%20reason%20and%20a%20date%20range%2C%20and%20a%20Download%20CSV%20button%20that%20exports%20whatever%20is%20filtered%20with%20the%20columns%20from%20point%202.%0A4.%20A%20daily%20digest%20posted%20to%20Slack%20via%20SLACK_WEBHOOK_URL%20at%20DIGEST_TIME%20\(HH%3AMM%20in%20TIMEZONE%2C%20default%2007%3A30\).%20Content%2C%20in%20Slack%20mrkdwn%3A%0A%20%20%20*Sold%20out%20yesterday%20%E2%80%94%20%3Cvenue%20name%3E%2C%20%3Cdate%3E*%0A%20%20%20One%20line%20per%20item%2C%20in%20time%20order%3A%20%2214%3A20%20%20Margherita%20Pizza%20%E2%80%94%20sold%20out%20\(inventory\)%22%20or%20%2218%3A05%20%20Sea%20Bass%20%E2%80%94%20snoozed%20by%20staff%20until%2021%3A00%22.%20Group%20by%20venue%20if%20there%20is%20more%20than%20one.%0A%20%20%20Then%20a%20blank%20line%20and%20%22*Most%20sold%20out%20this%20month*%22%20followed%20by%20the%20top%20five%20items%20with%20counts.%0A%20%20%20If%20nothing%20sold%20out%20yesterday%2C%20post%20%22Nothing%20sold%20out%20yesterday.%22%20%E2%80%94%20still%20post%2C%20so%20I%20know%20the%20app%20is%20alive.%0A%20%20%20Post%20the%20digest%20once%20per%20day%20even%20if%20the%20app%20restarts%3A%20record%20the%20date%20of%20the%20last%20digest%20sent%20and%20skip%20if%20it%20has%20already%20been%20sent%20for%20that%20date.%0A5.%20A%20%22Send%20digest%20now%22%20button%20on%20the%20page%20for%20testing%2C%20which%20posts%20the%20digest%20for%20yesterday%20regardless%20of%20whether%20it%20was%20already%20sent.%0A6.%20GET%20%2Fhealth%20that%20returns%20200%20and%20%7B%20%22ok%22%3A%20true%20%7D%20and%20nothing%20else.%0A%0AUse%20TIMEZONE%20for%20every%20day%20boundary%20and%20displayed%20time.%20Do%20not%20guess%20a%20default%3A%20if%20TIMEZONE%20is%20unset%2C%20refuse%20to%20start%20and%20log%20a%20clear%20message.%0A%0ADEFINITION%20OF%20DONE%0A%0A-%20%5B%20%5D%20A%20signed%20item.out_of_stock%20event%20appears%20in%20the%20log%20within%20a%20second%20and%20the%20endpoint%20returned%20200.%0A-%20%5B%20%5D%20The%20same%20event%20delivered%20twice%20creates%20one%20row.%0A-%20%5B%20%5D%20A%20bad%20signature%20returns%20400%20and%20logs%20nothing.%0A-%20%5B%20%5D%20The%20example%20payload%20above%20shows%20as%20%22Margherita%20Pizza%20%E2%80%94%20snoozed%20by%20staff%20until%2018%3A00%22.%0A-%20%5B%20%5D%20The%20digest%20posts%20at%20DIGEST_TIME%20and%20not%20again%20that%20day%2C%20including%20after%20a%20restart.%0A-%20%5B%20%5D%20%22Send%20digest%20now%22%20posts%20to%20Slack%20immediately.%0A-%20%5B%20%5D%20The%20CSV%20download%20opens%20in%20a%20spreadsheet%20with%20one%20row%20per%20event%20and%20the%20columns%20listed.%0A-%20%5B%20%5D%20Restarting%20the%20app%20loses%20nothing.%0A%0AWHAT%20TO%20GIVE%20ME%20WHEN%20YOU%20ARE%20DONE%0A%0A1.%20The%20public%20webhook%20URL%20\(%E2%80%A6%2Fwebhooks%2Fstorekit\)%20and%20the%20page%20URL.%0A2.%20The%20environment%20variables%20to%20set%20\(STOREKIT_WEBHOOK_SECRET%2C%20ADMIN_PASSWORD%2C%20SLACK_WEBHOOK_URL%2C%20TIMEZONE%2C%20DIGEST_TIME\)%20and%20where%20to%20set%20them%20on%20this%20platform.%0A3.%20Confirmation%20that%20the%20app%20stays%20up%2024%20hours%20a%20day%20and%20that%20the%20scheduled%20job%20runs%20when%20nobody%20has%20the%20page%20open.%0A)

Either button opens the builder with the whole prompt below already filled in. Nothing starts until you press send, so read it through and edit the parts marked as yours first.

> **Prompt completo (clicca per espandere)**
>
> ```text theme={null}
> I want a small web app that keeps a log of every menu item that goes out of stock at my restaurant, and sends a short digest to Slack every morning. storekit tells the app about stock-outs by webhook. The app must never lose an event, never count the same event twice, and never make storekit wait.
>
> Build it with a database so the log survives restarts, an always-on public HTTPS URL, and a scheduled job for the digest.
>
> ```
>
> ```text theme={null}
> CONTEXT ABOUT STOREKIT
>
> I run a hospitality business on storekit (storekit.com), an online ordering and payments platform for restaurants, cafés and bars. storekit can notify my own app about things that happen in my store by sending webhooks.
>
> How storekit webhooks work:
> - Each event is an HTTP POST with a JSON body to a URL I register in the storekit dashboard.
> - The body has the shape { "event": "<event type>", "data": { ... } }. Two exceptions: the legacy order.created event (do not use it; use order.created.v2) sends the bare order object, and the order.refund.created / order.refund.succeeded / order.refund.failed events put order, customer, venue and refund next to event instead of inside data.
> - Requests are signed with Svix. Every request carries the headers svix-id, svix-timestamp and svix-signature. Verify them with the official `svix` library for your language, using a secret I will provide in an environment variable called STOREKIT_WEBHOOK_SECRET. Reject anything that fails verification with HTTP 400.
> - My endpoint must respond with a 2xx status within 15 seconds. Save the event to the database first, respond 200, then do the work from the saved copy.
> - Once I have responded 200, storekit will not send that event again, so the work must not be lost: store each event with a status (pending, done, failed) and only mark it done after the work has actually succeeded. On startup and on a timer, pick up anything still pending or failed and retry it. Never do the work only in memory after responding.
> - The same event can occasionally be delivered more than once. Use the svix-id header as the unique key for the saved event: a repeat of an event already saved is ignored, whatever its status.
> - Any page or endpoint protected by a password must be served over HTTPS only; redirect or refuse plain HTTP.
> - Money fields (total, tip, deliveryFee, discountTotal, item price, modifier price) are integers in minor units: 2500 means £25.00.
> - orderType is one of Delivery, Pickup, InStore, Curbside, CateringDelivery, CateringPickup or Billpay.
> - table is only present for in-store orders; deliveryAddress and pickUpTime only for delivery orders. When they do not apply the key is omitted, so treat a missing key the same as null. notes and items[].note can be null or empty. customer.companyName and customer.vatNumber appear only when supplied.
>
> Example order.created.v2 payload:
>
> {
>   "event": "order.created.v2",
>   "data": {
>     "id": "ord_abc123",
>     "code": "A1B2",
>     "asap": true,
>     "total": 2500,
>     "tip": 250,
>     "deliveryFee": 299,
>     "discountTotal": 0,
>     "orderType": "Delivery",
>     "pickUpTime": "2024-01-15T10:45:00Z",
>     "channel": "WEB",
>     "poNumber": null,
>     "createdAt": "2024-01-15T10:30:00Z",
>     "deliveryTime": "2024-01-15T11:00:00Z",
>     "notes": "Ring doorbell",
>     "customer": {
>       "firstName": "John",
>       "lastName": "Doe",
>       "email": "john@example.com",
>       "phone": "+44123456789",
>       "marketingConsent": true
>     },
>     "items": [
>       {
>         "name": "Margherita Pizza",
>         "printName": "Margherita",
>         "price": 1200,
>         "quantity": 1,
>         "plu": null,
>         "posId": null,
>         "taxRate": 20,
>         "note": null,
>         "modifiers": [
>           { "name": "Extra cheese", "printName": "Cheese", "price": 150, "quantity": 1, "plu": null, "posId": null, "taxRate": 20 }
>         ]
>       }
>     ],
>     "venue": {
>       "id": 1234,
>       "name": "My Restaurant",
>       "slug": "my-restaurant",
>       "address": {
>         "street1": "123 Main St",
>         "street2": "",
>         "city": "London",
>         "postCode": "W1A 1AA",
>         "country": "UK",
>         "companyName": "My Restaurant Ltd",
>         "coordinates": { "latitude": 51.5074, "longitude": -0.1278 }
>       }
>     },
>     "deliveryAddress": {
>       "street1": "456 Oak Ave",
>       "street2": "Flat 2",
>       "city": "London",
>       "postCode": "E1 6AN",
>       "country": "UK",
>       "notes": null,
>       "coordinates": { "latitude": 51.5155, "longitude": -0.0722 }
>     }
>   }
> }
>
> The full list of event types and payloads is at https://storekit.com/docs/developers/webhooks/webhook-events
> ```
>
> ```text theme={null}
> THE EVENT THIS APP USES: item.out_of_stock
>
> Ignore the order example above; this app only cares about item.out_of_stock, which looks like this:
>
> {
>   "event": "item.out_of_stock",
>   "data": {
>     "venue": { "id": 1234, "name": "My Restaurant" },
>     "item": { "id": 5678, "name": "Margherita Pizza", "plu": "PLU-001", "posId": "pos_item_42", "sku": "SKU-MARG-001" },
>     "reason": "snoozed",
>     "source": "manual",
>     "details": { "snoozeEnd": "2024-01-15T18:00:00Z" }
>   }
> }
>
> - reason is one of: snoozed (temporarily hidden by staff), inventory_depleted (sold out through inventory counts), disabled (switched off).
> - source is one of: manual (someone in the dashboard), order (a customer order used the last one), deliverect, lightspeed, zonal, pos_sync (pushed from a till or integration).
> - details.snoozeEnd is only present for reason snoozed and can be null, meaning snoozed indefinitely.
> - plu, posId and sku can be null.
> - There is no "back in stock" event. The app records when things went out; it cannot know when they came back.
>
> WHAT TO BUILD
>
> 1. POST /webhooks/storekit — verify the Svix signature with the official svix library and STOREKIT_WEBHOOK_SECRET against the raw request body; 400 on failure. Save the event and return 200 immediately. Ignore any svix-id already saved. Handle item.out_of_stock; save and acknowledge any other event type but do nothing with it.
> 2. A log table with: received time (store UTC, display in TIMEZONE), venue name, item name, item id, plu, sku, reason, source, snoozeEnd. Record the event's time as the time the webhook arrived.
> 3. GET / — protected by HTTP basic auth with ADMIN_PASSWORD. Three things on one page:
>    a. "Yesterday and today": a list of stock-outs since the start of yesterday in TIMEZONE, newest first, showing time, item, reason and source in plain words ("Snoozed by staff until 18:00", "Sold out through inventory after an order", "Switched off from Zonal").
>    b. "Most sold out, last 30 days": items ranked by number of stock-outs, with the count and the most common hour of day it happens.
>    c. Filters for venue (if I have more than one), reason and a date range, and a Download CSV button that exports whatever is filtered with the columns from point 2.
> 4. A daily digest posted to Slack via SLACK_WEBHOOK_URL at DIGEST_TIME (HH:MM in TIMEZONE, default 07:30). Content, in Slack mrkdwn:
>    *Sold out yesterday — <venue name>, <date>*
>    One line per item, in time order: "14:20  Margherita Pizza — sold out (inventory)" or "18:05  Sea Bass — snoozed by staff until 21:00". Group by venue if there is more than one.
>    Then a blank line and "*Most sold out this month*" followed by the top five items with counts.
>    If nothing sold out yesterday, post "Nothing sold out yesterday." — still post, so I know the app is alive.
>    Post the digest once per day even if the app restarts: record the date of the last digest sent and skip if it has already been sent for that date.
> 5. A "Send digest now" button on the page for testing, which posts the digest for yesterday regardless of whether it was already sent.
> 6. GET /health that returns 200 and { "ok": true } and nothing else.
>
> Use TIMEZONE for every day boundary and displayed time. Do not guess a default: if TIMEZONE is unset, refuse to start and log a clear message.
>
> DEFINITION OF DONE
>
> - [ ] A signed item.out_of_stock event appears in the log within a second and the endpoint returned 200.
> - [ ] The same event delivered twice creates one row.
> - [ ] A bad signature returns 400 and logs nothing.
> - [ ] The example payload above shows as "Margherita Pizza — snoozed by staff until 18:00".
> - [ ] The digest posts at DIGEST_TIME and not again that day, including after a restart.
> - [ ] "Send digest now" posts to Slack immediately.
> - [ ] The CSV download opens in a spreadsheet with one row per event and the columns listed.
> - [ ] Restarting the app loses nothing.
>
> WHAT TO GIVE ME WHEN YOU ARE DONE
>
> 1. The public webhook URL (…/webhooks/storekit) and the page URL.
> 2. The environment variables to set (STOREKIT_WEBHOOK_SECRET, ADMIN_PASSWORD, SLACK_WEBHOOK_URL, TIMEZONE, DIGEST_TIME) and where to set them on this platform.
> 3. Confirmation that the app stays up 24 hours a day and that the scheduled job runs when nobody has the page open.
> ```

Apri l'app, premi "Send digest now" e verifica che Slack mostri "Nothing sold out yesterday." prima di collegare storekit.

## Step 2: collega storekit

**1. Open the webhooks portal**

In the dashboard sidebar, go to **Settings** → **Webhooks**. If your plan includes webhooks and they are not yet enabled, click **Enable Webhooks**. If the page shows **Upgrade to enable webhooks**, [contact support](/docs/getting-started/contact-support) to discuss adding webhooks to your plan.

**2. Add your app as an endpoint**

In the embedded portal, add a new endpoint, paste the webhook URL your app builder gave you, and tick only the event types the recipe needs.

**3. Copy the signing secret into your app**

Open the endpoint you just created and copy its signing secret. In your app builder, save it as the environment variable `STOREKIT_WEBHOOK_SECRET` (builders call this "secrets" or "environment variables"). Redeploy if the builder asks you to.

**4. Send a test event**

Use the portal's test option on the endpoint to send a sample event. The delivery log shows the response code from your app. A `2xx` means your app accepted it; anything else, read the response body in the log — it is usually a missing secret.

Seleziona solo `item.out_of_stock` per questo endpoint.

## Step 3: testa con un esaurimento reale

Sospendi un articolo dal menu builder (vedi [Sospensione dei prodotti](/docs/it/guides/menu/availability-snoozing#snoozing-products)). Entro pochi secondi compare una riga nell'app con reason "snoozed" e source "manual". Riattiva l'articolo dopo il test — l'app non lo registra, come previsto.

## Idee

* **Email settimanale al buyer**: chiedi al builder di aggiungere un'email del lunedì (tramite un provider come Resend o Postmark) con la tabella dei 30 giorni allegata in CSV.
* **Lista prep**: marca gli articoli che si esauriscono prima delle 20 per tre volte in una settimana come "sotto-preparati" ed elencali separatamente.
* **Controllo incrociato con la cassa**: filtra per `source` per vedere quanto spesso il tuo POS nasconde articoli che pensavi fossero in vendita.

## Cosa non fa

* **Non può dirti quando un articolo è tornato disponibile**, perché non esiste un evento "back in stock". Leggi il log come "è uscito alle", non come "è stato fuori per".
* **Non modifica la disponibilità.** Riattivare e rifornire avvengono ancora nella dashboard o sulla tua cassa come prima.
* **Gli eventi partono dal momento in cui colleghi l'endpoint.** Prima di quel momento non c'è storia; la tabella dei 30 giorni si riempie nel corso del primo mese.
* **È il tuo servizio.** Il supporto storekit può confermare che un evento `item.out_of_stock` ha raggiunto il tuo URL e il codice di risposta; il log e il riepilogo sono tuoi.

## Correlati

> **[Payload item.out\_of\_stock](/docs/it/developers/webhooks/webhook-events#item-out-of-stock)**
>
> Ogni valore di reason e source che l'evento può portare.

> **[Scrivere un prompt che funziona](/docs/it/guides/build/prompting-guide)**
>
> La struttura dietro questo prompt e cosa dire quando il builder sbaglia.

> **[Avvisi ordini su Slack o telefono](/docs/it/guides/build/recipes/order-alerts)**
>
> Lo stesso pattern per gli ordini invece che per le scorte.

> **[Disponibilità e sospensione](/docs/it/guides/menu/availability-snoozing)**
>
> Sospensione, inventario e il report degli snooze integrato.


## Related topics

- [Costruisci i tuoi strumenti su storekit](/docs/it/guides/build/overview.md)
- [Audit log](/docs/it/privacy-security/audit-log.md)
- [Banner promozionali](/docs/it/guides/marketing/promotional-banners.md)
- [Disponibilità e sospensione](/docs/it/guides/menu/availability-snoozing.md)
- [Risoluzione dei problemi del tuo agente AI](/docs/it/guides/ai/troubleshooting.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.