Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Crafting a Great Webhooks Experience
Search
John Sheehan
August 21, 2014
Technology
220
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Crafting a Great Webhooks Experience
Presented at API Craft SF on 8/21/14
John Sheehan
August 21, 2014
More Decks by John Sheehan
See All by John Sheehan
My Favorite API Tools (Other than Runscope)
johnsheehan
0
190
Crafting a Great Webhooks Experience
johnsheehan
2
550
Glue 2015: Microservices - More than just a buzzword.
johnsheehan
2
770
Scale-Oriented Architecture with Microservices
johnsheehan
2
380
The rise of distributed applications.
johnsheehan
2
500
Zen and the Art of API Maintenance
johnsheehan
2
2.5k
Building API integrations you can live with.
johnsheehan
0
140
Free API debugging and testing tools you should know about.
johnsheehan
5
870
Modern Tools for Modern Applications
johnsheehan
1
210
Other Decks in Technology
See All in Technology
機械学習を「社会実装」するということ 2026年夏版 / Social Implementation of Machine Learning June 2026 Version
moepy_stats
6
2.4k
Socrates × Looker 〜セマンティックレイヤーで進化するデータ分析エージェント〜
hanon52_
3
2.4k
2026TECHFRESH畢業分享會 - 原生還是跨平台? App 開發踩坑實錄
line_developers_tw
PRO
0
1.1k
新しいVibe Codingと”自走”について
watany
6
330
AIっぽい文章を採点して人間らしく直すアプリを作ってみた
yama3133
2
200
小さくはじめるSLI/SLO ~育てながら組織に定着させる実践知~ / Starting Small with SLI/SLOs: Building Adoption Through Continuous Growth
nari_ex
7
2k
【Snowflake Summit 2026 Recap!!】Snowflake Summit Deep Dive: Security & Governance
civitaspo
1
220
非エンジニアがClaudeと挑んだ「1ヶ月間プロダクト30本ノック」
askokc
0
580
なぜ Platform Engineering の土台に Kubernetes を選ぶのか
r4ynode
2
650
Kubernetesにおける学習基盤とLLMOpsの概要
ry
1
310
小さく始める AI 活用推進 ― 日経電子版 Web チームの事例/nikkei-tech-talk47
nikkei_engineer_recruiting
0
270
作って終わりにしない タイミーのセマンティックレイヤー育成の現在地
chanyou0311
4
2.4k
Featured
See All Featured
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
Making the Leap to Tech Lead
cromwellryan
135
9.9k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
580
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
470
The Cost Of JavaScript in 2023
addyosmani
55
10k
Are puppies a ranking factor?
jonoalderson
1
3.6k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
310
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
390
Skip the Path - Find Your Career Trail
mkilby
1
150
Paper Plane (Part 1)
katiecoart
PRO
0
9k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
180
Transcript
Crafting a Great Webhooks Experience John Sheehan CEO, @Runscope Tuesday,
October 7, 14
Tuesday, October 7, 14
Tuesday, October 7, 14
Tuesday, October 7, 14
Tuesday, October 7, 14
Tuesday, October 7, 14
"user defined callbacks made with HTTP POST" Tuesday, October 7,
14
"Webhooks are the easiest way to remotely execute code." --
Jeff Lindsay once when we were talking Tuesday, October 7, 14
HTTP Push Notifications Tuesday, October 7, 14
A Reverse API Tuesday, October 7, 14
Provider makes request to URL when an event happens. Consumer
sets up a server to listen for callbacks. Consumer registers callback URL with provider. Tuesday, October 7, 14
Provider makes request to URL when an event happens. Consumer
sets up a server to listen for callbacks. Consumer registers callback URL with provider. Tuesday, October 7, 14
Provider makes request to URL when an event happens. Consumer
sets up a server to listen for callbacks. Consumer registers callback URL with provider. Tuesday, October 7, 14
Tuesday, October 7, 14
Implementing Webhooks Tuesday, October 7, 14
url = get_callback_url() data = get_webhook_payload_json() try: resp = requests.post(url,
data=data) if not resp.ok: _logger.error(resp.content) except Exception as e: _logger.error(e) Tuesday, October 7, 14
Problem #1: Error Handling Tuesday, October 7, 14
> POST /callback < 400 Bad Request Tuesday, October 7,
14
> POST /callback < 302 Found < Location: http:// Tuesday,
October 7, 14
> POST /callback < 200 OK < Content-Type: text/plain <
<Response></Response> Tuesday, October 7, 14
Error Handling Suggestions Tuesday, October 7, 14
Be lenient in what you accept back if you can
reasonably guess. Retry failed callbacks with exponential back off. Decide if redirects are to be followed or not. Tuesday, October 7, 14
Be lenient in what you accept back if you can
reasonably guess. Retry failed callbacks with exponential back off. Decide if redirects are to be followed or not. Tuesday, October 7, 14
Be lenient in what you accept back if you can
reasonably guess. Retry failed callbacks with exponential back off. Decide if redirects are to be followed or not. Tuesday, October 7, 14
Problem #2: Flooding Tuesday, October 7, 14
Tuesday, October 7, 14
Active Queues ↪ ↪ Tuesday, October 7, 14
Problem #3: Security Tuesday, October 7, 14
> POST http://localhost:3000 Tuesday, October 7, 14
> POST http://foo.lvh.me Tuesday, October 7, 14
DoS Attack Vector Tuesday, October 7, 14
Proving the Source Tuesday, October 7, 14
Validation Techniques Tuesday, October 7, 14
Key Sharing Tuesday, October 7, 14
Request Signing Tuesday, October 7, 14
Re-fetch > POST /callback > { id: 123 } >
GET /users/123 < { id: 123 } Webhook Callback App Code Tuesday, October 7, 14
Security Suggestions Tuesday, October 7, 14
Validate your requests. Document it well! Resolve IPs before making
request. Consider proxying. Consider subscription validation for high-volume cases. Tuesday, October 7, 14
Validate your requests. Document it well! Resolve IPs before making
request. Consider proxying. Consider subscription validation for high-volume cases. Tuesday, October 7, 14
Validate your requests. Document it well! Resolve IPs before making
request. Consider proxying. Consider subscription validation for high-volume cases. Tuesday, October 7, 14
Developer Experience Tuesday, October 7, 14
Payload Design Tuesday, October 7, 14
Fat vs.Thin Tuesday, October 7, 14
- or - { } payload= Tuesday, October 7, 14
- or - data = JSON.loads(request.body) name = data["name"] name
= request.form.get("name") Tuesday, October 7, 14
payload = request.form.get("payload") data = JSON.loads(payload) name = data["name"] Tuesday,
October 7, 14
Mirror API Resources Tuesday, October 7, 14
Complete Documentation! Tuesday, October 7, 14
Tooling Tuesday, October 7, 14
Accept Multiple Callback URLs Tuesday, October 7, 14
Hooks API Tuesday, October 7, 14
Debugger & Logs Tuesday, October 7, 14
Manual Retries Tuesday, October 7, 14
Generate Test Callbacks Tuesday, October 7, 14
Tunneling Tuesday, October 7, 14
Thank you! Questions? Try Runscope free: runscope.com Tuesday, October 7,
14