Install
$ agentstack add skill-pvnarp-agent-skills-api-integration ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
API Integration
You don't control external APIs. They change, they break, they go down, and they rate-limit you. Design for all of this.
Client Design
The Wrapper Pattern
Never call a third-party API directly from business logic. Always wrap it.
Business Logic → Your Wrapper → Third-Party SDK/HTTP Client → External API
Why:
- Swap vendors without changing business logic
- Add retry logic, circuit breaker, logging in one place
- Mock the wrapper in tests (not the HTTP client)
- Normalize error types to your domain
Wrapper Structure
services/
payments/
client.ts # HTTP client, auth, retry logic
types.ts # Your domain types (not vendor types)
mapper.ts # Vendor response → your types
errors.ts # Vendor errors → your error types
Rules:
- Vendor types NEVER leak into business logic
- Map vendor responses to your own types immediately
- Map vendor errors to your own error types
- Business logic depends on YOUR interface, not the vendor's
Authentication Patterns
API Key
Header: Authorization: Bearer sk_live_xxx
or: X-API-Key: xxx
- Store in secret manager, never in code
- Rotate on schedule
- Use separate keys per environment
OAuth2 Client Credentials
1. Exchange client_id + client_secret for access token
2. Cache the access token until expiry
3. Refresh BEFORE it expires (with buffer)
4. Retry once with fresh token on 401
Token refresh pattern:
Request fails with 401
→ Is this a retry already? YES → fail (don't loop)
→ Refresh the token
→ Retry the original request with new token
Webhook Signature Verification
1. Extract signature from header (e.g., X-Signature-256)
2. Compute HMAC-SHA256 of raw request body with your webhook secret
3. Compare (constant-time!) your computed signature with the received one
4. Reject if mismatch - someone is spoofing webhooks
Never skip signature verification. It's the only thing preventing attackers from injecting fake events.
Rate Limit Handling
Reactive (Handle 429)
Request → 429 Too Many Requests
→ Read Retry-After header
→ Wait that long
→ Retry
Proactive (Stay Under Limits)
- Track your request count per time window
- Implement client-side rate limiting (token bucket, leaky bucket)
- Queue requests and drain at the allowed rate
- Log when approaching limits (80% threshold)
Rate Limit Response Headers
X-RateLimit-Limit: 100 # Max requests per window
X-RateLimit-Remaining: 23 # Remaining in current window
X-RateLimit-Reset: 1710500000 # Unix timestamp when window resets
Retry-After: 30 # Seconds to wait (on 429)
Retry Strategy
Retryable: 429, 500, 502, 503, 504, connection timeout, DNS failure
NOT retryable: 400, 401, 403, 404, 409, 422 (client errors - fix your request)
attempt 1: immediate
attempt 2: 200ms + jitter
attempt 3: 800ms + jitter
attempt 4: 3200ms + jitter
give up → log, DLQ, or return error
Rules:
- Only retry idempotent operations (or use idempotency keys)
- Cap total retry time (don't retry for 10 minutes)
- Log every retry with attempt number and error
- Circuit break if too many retries are happening
Idempotency Keys
For non-idempotent operations (creating charges, sending emails), use idempotency keys:
POST /v1/charges
Idempotency-Key: charge_req_abc123
{ amount: 5000, currency: "usd" }
If the request fails ambiguously (timeout, network error), retry with the same idempotency key. The API returns the original result instead of creating a duplicate.
Generate idempotency keys from your domain: charge_{order_id}_{attempt} - deterministic and meaningful.
Webhook Processing
Receiving Webhooks
1. Verify signature (ALWAYS)
2. Return 200 immediately (don't process inline)
3. Queue the event for async processing
4. Process from queue with retry logic
5. Idempotent handling (same event may arrive twice)
Why return 200 immediately? If your processing takes > 5s, the sender may time out and retry, causing duplicates.
Webhook Event Handling
Receive webhook event
→ Verify signature
→ Store raw event in database
→ Return 200
→ Async: process event
→ Check: have I already processed this event ID?
YES → skip (idempotent)
NO → process and record event ID as processed
Webhook Reliability
External webhooks WILL fail. Design for it:
- Don't depend on webhooks for critical flows (poll as backup)
- Store raw webhook payload for replay
- Monitor: are expected webhooks arriving? Alert on silence.
Timeout Configuration
Every external call needs a timeout. No exceptions.
| Timeout Type | Typical Value | Purpose | |-------------|---------------|---------| | Connection timeout | 5s | Give up connecting | | Read timeout | 30s | Give up waiting for response | | Total timeout | 60s | Give up on the entire operation |
Without timeouts: One slow API call blocks your thread/connection forever, eventually exhausting your pool and taking down your service.
Testing
Unit Tests
Mock your wrapper (not the HTTP client). Test that your code handles:
- Successful responses (mapped to your types correctly)
- Error responses (mapped to your error types)
- Timeouts
- Rate limiting (429 handling)
- Auth failures (401 → refresh → retry)
Contract Tests
Verify your expectations match the API's actual behavior:
- Record real API responses
- Replay them in tests
- Detect when the API changes (before production breaks)
Sandbox/Test Mode
Most APIs have sandbox environments. Use them in staging:
- Stripe test mode, Twilio test credentials, etc.
- Never call production APIs from tests
> Reference: reference/integration-patterns.md - rate limiting strategies, auth pattern comparison, webhook reliability, circuit breaker, SDK vs HTTP decision, vendor API patterns, timeout strategy.
Anti-Patterns
| Anti-Pattern | Problem | Fix | |-------------|---------|-----| | Direct API calls in business logic | Tight coupling, untestable, no retry | Wrap in a service with its own interface | | No timeout | Thread blocked forever on slow API | Set connection + read + total timeouts | | Retry everything | Retrying 400 errors wastes quota | Only retry transient errors (5xx, timeouts) | | Vendor types in domain | API change breaks everything | Map to your own types at the boundary | | Trust webhook without verifying | Attackers can inject fake events | Always verify signatures | | Process webhook synchronously | Timeouts cause duplicate deliveries | Return 200 fast, process async |
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: pvnarp
- Source: pvnarp/agent-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.