今日已更新 233 条资讯 | 累计 20205 条内容
关于我们

标签:#api

找到 307 篇相关文章

AI 资讯

Why I Built My Own Rate Limiting Library for FastAPI

This was originally posted on my blog . I was not planning to build a rate limiting library. I had a FastAPI project, I needed rate limiting, I reached for SlowAPI, which is the most popular choice for FastAPI, and wired it up. Took maybe 20 minutes. Then I started actually using it. The request: Request problem The first thing that got to me was the request: Request requirement. SlowAPI's decorator needs access to the request to extract the client IP or user ID, and the only way it can get that is if your route function accepts it as a parameter. So every rate-limited route ends up looking like this: @app.get ( " /items " ) @limiter.limit ( " 10/minute " ) async def get_items ( request : Request ): return await fetch_items () That request: Request is not doing anything. fetch_items() does not use it. It's there purely because SlowAPI needs it. Small thing, but it bothered me — I like function signatures that say exactly what they need, and this one was lying. The header injection problem I could live with that. The thing I could not live with was the header injection. Rate limit headers are genuinely useful — X-RateLimit-Remaining tells clients when to back off, Retry-After tells them how long to wait. Standard stuff. So I enabled SlowAPI's header injection and immediately hit a wall: every rate-limited route now had to return a Response object directly. Not a dict. Not a Pydantic model. A Response . The moment you enable header injection, SlowAPI expects to work with an actual response object, and if your route returns anything else it just breaks. So I was suddenly doing this: @app.get ( " /items " ) @limiter.limit ( " 10/minute " ) async def get_items ( request : Request , response : Response ): items = await fetch_items () return JSONResponse ( content = jsonable_encoder ( items )) Which is annoying because one of the things I actually like about FastAPI is that you declare a return type, FastAPI handles the serialization, and your OpenAPI schema just works. Sl

2026-06-21 原文 →
开发者

Introducing Stardust API Engine

Hey developers! 🚀 I wasted too much time setting up dummy backends just to test my frontend designs. So, I built Stardust API Engine — a completely free, serverless mock server. What it does: Instant live endpoints for /users and /products (Ready to fetch() ). In-built Custom JSON Data Generator to structure your own schemas. 100% serverless, zero login friction, and lightning fast. Check it out here: https://stardustofficial.github.io/stardust-api/ Feedback is highly appreciated! Built with 🌌 by Zishan.

2026-06-21 原文 →
AI 资讯

Chaos Engineering for Node.js Without the Infrastructure

Chaos engineering sounds expensive. Netflix built Chaos Monkey to randomly kill production servers. Google runs DiRT (Disaster Recovery Testing) across their entire infrastructure. Amazon does game days where they intentionally take down services. You're building a Node.js API. You don't have a platform team. You don't have a chaos infrastructure. But you still need to know: what happens when your dependencies get slow? The good news is that 80% of the value of chaos engineering comes from one question, and you can answer it locally in five minutes. The one question that matters What does my application do when a dependency responds slowly or not at all? Not "what if the server catches fire" — that's infrastructure chaos. What about application chaos: the database is slow, the payment API is timing out, Redis is having a bad day. These happen constantly in production and they're almost never tested. The failure modes look like this: Your DB gets slow under load → your API response times climb → your timeout fires → you retry → now you're sending twice the load to an already-slow DB Your Redis cache goes down → every request hits Postgres directly → Postgres gets slow → same cascade Stripe's API takes 3 seconds instead of 200ms → your checkout route times out → users get errors → you're losing revenue Every one of these is a latency failure , not a crash. The service is still up. It's just slow. And slow is the hardest failure mode to test because your local environment is fast. Why local testing misses this When you test locally, your "database" is either: A real local Postgres running on the same machine (sub-millisecond latency, not production-like) A mock that returns instantly ( jest.fn().mockResolvedValue(data) ) A fake with a flat delay ( await sleep(200) ) None of these produce realistic latency. A real production database has: Fast responses most of the time (p50 ~5ms) Occasional slowdowns (p95 ~50ms) Rare but real spikes (p99 ~200ms, p99.9 ~2000ms) The spik

2026-06-21 原文 →
AI 资讯

How Calendar Synchronization Works in Multi‑Channel Rental Platforms

Calendar synchronization is one of the most challenging parts of building a multi‑channel rental platform. Every booking, cancellation, modification, or pricing update must propagate across all connected channels quickly and without conflicts. A single missed update can lead to double bookings, lost revenue, or unhappy guests. Why calendar sync is difficult Calendar data is dynamic and often inconsistent across platforms. Common issues include: out‑of‑order updates, conflicting changes from different sources, slow or rate‑limited APIs, missing or duplicated events, timezone inconsistencies, partial updates that overwrite each other. A reliable sync engine must handle all of these edge cases gracefully. Core principles of a robust calendar sync A well‑designed sync system follows several key rules: Event‑driven updates: every change triggers an event rather than a full resync. Incremental synchronization: only changed data is processed. Conflict resolution: timestamps or version numbers determine the winning update. Idempotency: repeated updates produce the same result. Queue‑based processing: heavy operations run asynchronously. Audit logs: every update is traceable. These principles ensure that calendars remain consistent even under heavy load. Real‑world example Short‑term rental platforms rely on accurate calendars to avoid double bookings. A good example of this approach can be seen in an event‑driven short‑term rental calendar synchronization system , where each update is processed through queues, validated, and applied idempotently. If you want to explore how a real SaaS platform handles calendar synchronization, you can check PMS.Rent Conclusion Calendar synchronization is not just a technical feature — it is the foundation of trust between property managers and their tools. When the sync engine is event‑driven, idempotent, and conflict‑aware, the entire platform becomes more reliable and predictable.

2026-06-21 原文 →
AI 资讯

Designing a Reliable Sync Engine for Multi‑Channel SaaS Platforms

A sync engine is one of the most critical components in any SaaS platform that integrates with external services. Whether you manage bookings, payments, messages, or inventory, the system must stay consistent across multiple channels without losing data or creating conflicts. Why sync engines fail Most sync issues come from predictable technical problems: API rate limits. Slow or unstable external endpoints. Conflicting updates from different sources. Missing retry logic. Lack of idempotency. When these issues accumulate, the platform becomes unreliable and difficult to scale. Key principles of a reliable sync engine A well‑designed sync engine follows several core principles: Event sourcing to track every change. Message queues to handle spikes in traffic. Idempotent operations to avoid duplicates. Timestamp‑based conflict resolution. Retry and backoff strategies for unstable APIs. These patterns ensure that the system remains consistent even when external services behave unpredictably. Real‑world example Platforms that manage short‑term rental operations rely heavily on sync engines. Calendar updates, pricing changes, and new bookings must be processed in real time. A good example of an event‑driven sync model can be seen in modern PMS systems. For instance, the approach used in event‑driven property management architecture is similar to the one implemented in PMS.Rent Conclusion A sync engine is not just a background process — it is the backbone of any API‑driven SaaS platform. When designed correctly, it ensures reliability, scalability, and predictable behavior across all integrated channels.

2026-06-20 原文 →
AI 资讯

60–95% fewer tokens in your agent loops, same answers. Meet Headroom.

AI coding agents are expensive — not because models cost too much per token, but because they send too many of them. An SRE debugging session with a raw agent: 65,694 tokens in. With Headroom in the middle: 5,118. Same bug found. Headroom is a new open-source context compression layer that intercepts everything your agent reads — tool outputs, log dumps, RAG chunks, files, conversation history — and compresses it before the LLM ever sees it. It's local, reversible, and available as a drop-in proxy, a library, or an MCP server. The numbers that matter Savings on real agent workloads: Code search (100 results): 17,765 → 1,408 tokens (92% reduction) SRE incident debugging: 65,694 → 5,118 tokens (92%) GitHub issue triage: 54,174 → 14,761 tokens (73%) Codebase exploration: 78,502 → 41,254 tokens (47%) Accuracy on standard benchmarks (GSM8K, TruthfulQA, SQuAD v2, BFCL) is preserved — some scores actually improve slightly, likely because the model sees cleaner signal. What's doing the compression Under the hood, Headroom routes content through a stack of specialised compressors: SmartCrusher — JSON, nested objects, arrays of dicts CodeCompressor — AST-aware for Python, JS, Go, Rust, Java, C++ Kompress-base — a custom HuggingFace model trained on agentic traces, for prose and mixed content CacheAligner — stabilises prompt prefixes so Anthropic/OpenAI KV caches actually hit It also does CCR (reversible compression) — originals are cached locally and the LLM can retrieve them on demand if it needs them. Nothing is destroyed. Why the proxy mode matters The most interesting deployment path: headroom proxy --port 8787 , then point your existing tool at localhost. Zero code changes. Works with any language. Or even simpler: headroom wrap claude wraps Claude Code, routes its traffic through Headroom automatically. One command, savings start immediately. Same for Codex, Cursor, Aider, Copilot CLI. "Library — compress(messages) in Python or TypeScript, inline in any app. Proxy — hea

2026-06-20 原文 →
AI 资讯

The hard part of national ID OCR isn't the OCR

You wire up OCR for your KYC flow, point it at a national ID card, and get back a clean { name, idNumber, dateOfBirth } . Ship it. Then you onboard your second country — and it falls apart. Fields you mapped don't exist. The name comes back as garbled Latin. The date of birth says the year 2567. Here's the thing nobody tells you when you start: the hard part of national ID OCR isn't the OCR. It's that every country's ID is a different document. A model that reads text off a card is table stakes. Turning 30 countries' cards into data your system can actually use is where the work is. Let me show you the three axes of variation that will bite you, then how to architect so they don't. Axis 1: the fields are different There is no universal "national ID" schema, because the cards themselves don't agree on what to print. A Thai ID card prints the holder's religion . A German ID card prints height and eye color . A Chinese ID card prints ethnicity and the issuing authority. None of these are edge cases — they're core fields on those documents. So the instinct to define one IdCard type with a fixed set of columns is wrong from day one. Either you drop information that some countries consider essential, or you end up with a sparse table full of null s and country-specific special-casing. And it's not just which fields exist — it's what they're called and how they're split. The same "name" concept might come back as a single full-name string on one card and as separate given/family fields on another, sometimes in two scripts at once. Your data model has to treat "the field set depends on the country" as a first-class fact, not an afterthought. Axis 2: the script is different If your users are global, a lot of their names are not in the Latin alphabet — Chinese, Thai, Arabic, and more. The naive move is to transliterate everything to Latin "so it's consistent." Don't. Transliteration is lossy and ambiguous: multiple native spellings collapse to the same Latin form, diacritics

2026-06-19 原文 →
AI 资讯

The stock-analysis API you don't have to build

I was building a feature that needed to say something useful about a stock — not just print its P/E, but actually read the situation: is this cheap or expensive, what's the bull case, is the insider buying real or routine. I went looking for an API. Every finance API I found sold me raw data . Alpha Vantage, Twelve Data, Yahoo Finance, FMP — they'll hand you fundamentals, prices, filings, all of it. Great. Now I get to write the part that turns 40 metrics into "this looks expensive but the moat is widening." That's the part that's actually hard, and the part I didn't want to own forever. So I'd be wiring three data providers, normalizing their conflicting field names, writing and tuning the LLM prompts, handling the rate limits and the caching, and then maintaining all of it as the upstreams change. For a feature, not a product. What I wanted instead A single endpoint. Ticker in, analysis out — already synthesized, already structured. That's what I ended up building for myself and then put on RapidAPI: Agent Toolbelt — AI Stock Research API . It pulls live fundamentals from Polygon, Finnhub, and Financial Modeling Prep, then returns a Motley-Fool-style read as typed JSON. The numbers are in there too, but the point is the verdict and the reasoning. Here's a real stock-thesis response: { "verdict" : "bullish" , "oneLiner" : "Nvidia owns the essential infrastructure for the AI revolution with a defensible software moat." , "keyStrengths" : [ "~80%+ data center GPU market share" , "CUDA moat creates switching costs" , "42 buy / 5 hold / 1 sell analyst consensus" ], "keyRisks" : [ "36.9x P/E leaves no margin for error" , "Competition from AMD and custom silicon" ], "insiderRead" : "Two executives bought ~47k shares each — meaningful open-market purchases, not routine grants." , "dataSnapshot" : { "currentPrice" : 180.4 , "peRatio" : 36.9 , "marketCapBillions" : 4452.2 } } That's one HTTP call. No data-provider accounts, no prompt engineering, no normalization layer. The

2026-06-19 原文 →
AI 资讯

Ky 2.0 Fetch API Wrapper with Revamped Hooks, Smarter Timeouts, and Built-In Schema Validation

Ky 2.0 is an open-source JavaScript HTTP client built on the Fetch API, featuring significant updates such as consolidated hook handling, enhanced timeout management, and improved URL processing. The release includes response validation through schema validation libraries and addresses migration from earlier versions. It aims to provide a lightweight alternative to axios. By Daniel Curtis

2026-06-18 原文 →
AI 资讯

I Replaced 5 Social Media APIs With One Key (and My Code Got Way Simpler)

A while back I was building a side project that needed public data from a few social platforms. Nothing crazy — profiles, posts, some engagement numbers. I figured I'd just grab each platform's official API. Reader, I did not "just grab each platform's official API." Here's what that road actually looked like, and how I ended up consolidating everything down to one key and roughly ten lines of shared code. The five-API nightmare Instagram (Meta Graph API). Great if you own the account. Useless for pulling public data about accounts you don't. Endless app review. TikTok. The research API is academics-only with a long application. For commercial use, basically nothing. X (Twitter). Used to be wonderful. Now $100/month to start, more for anything serious. YouTube. Honestly the best of the bunch — generous and well-documented. Credit where due. LinkedIn. Partner-only. For most people, no useful public access at all. So to cover five platforms I was looking at: five sets of credentials, five auth flows, five rate-limit models, five totally different response shapes, two flat-out rejections, and a monthly bill. For a side project. What I actually wanted getProfile ( " tiktok " , " someuser " ) getProfile ( " instagram " , " someuser " ) getProfile ( " twitter " , " someuser " ) Same call shape, same auth, same error handling. That's it. I don't care that each platform structures things differently internally — I want one boundary that hides that from me. The consolidation I switched to SociaVault , which puts public data from all of these behind one API and one key. My entire client became this: const API_KEY = process . env . SOCIAVAULT_API_KEY ; const BASE = " https://api.sociavault.com " ; async function sv ( path , params = {}) { const url = new URL ( BASE + path ); Object . entries ( params ). forEach (([ k , v ]) => url . searchParams . set ( k , v )); const res = await fetch ( url , { headers : { " X-API-Key " : API_KEY } }); if ( ! res . ok ) throw new Error ( ` $

2026-06-18 原文 →
AI 资讯

Stop Fighting Python for Webhooks: Why Node.js is Optimal for Cloud Function Signatures

The Cryptographic Trust Problem (Why Webhooks Are Unforgiving) Webhooks are the nervous system of modern production apps. Whether you are processing a payment on Stripe, tracking a subscription on Lemon Squeezy, or fulfilling an order via Shopify, webhooks are how external platforms tell your backend: "Hey, something important just happened". Because these webhook endpoints have to be publicly accessible, they are prime targets for malicious actors. To prevent this, platforms use cryptographic signature verification . The Golden Rule of Verification When a provider sends a webhook, they take the HTTP request body and hash it with a shared secret key using HMAC-SHA256 . They pass this resulting signature in the request headers (like Stripe-Signature). When the request hits your server, your code has to do the exact same math: Grab the shared secret. Grab the exact raw bytes of the incoming request body. Hash them together and compare your result with the signature in the header. This process is completely binary and zero-tolerance. If your backend framework alters even a single byte—adding a trailing newline, stripping a whitespace, or reordering a JSON key during parsing—the math changes entirely. The signatures won't match, and the verification will fail. This brings us to our fundamental architectural bottleneck: to verify a webhook, you must intercept the request before your framework touches it. Why Python/Werkzeug Struggles If you build a Cloud Function in Python using the Firebase Functions SDK, you are working on top of Flask, which relies on Werkzeug to handle the underlying web server mechanics. Werkzeug is fantastic for standard web apps, but it has a specific architectural design that makes webhook verification a nightmare: it treats the incoming request body as a one-time, sequential input stream. The Single-Consumption Stream Under the WSGI (Web Server Gateway Interface) standard that powers Python web frameworks, the network payload arrives as an activ

2026-06-18 原文 →
AI 资讯

From Pixels to Proteins: Building a Precise Dietary Analysis System with GPT-4o and SAM

Have you ever tried to track your calories by manually searching for "half-eaten avocado toast" in a database? It’s a nightmare. While basic AI Computer Vision can identify an "apple," traditional models often fail at the granular level—distinguishing between 100g and 250g of pasta or identifying hidden toppings in a complex salad. In this tutorial, we are building a high-precision food nutrition AI engine. By combining the Segment Anything Model (SAM) for pixel-perfect object isolation and GPT-4o Vision for multi-modal reasoning and volume estimation, we can transform a simple smartphone photo into a detailed nutritional report. If you’re looking to dive deeper into production-grade AI patterns, I highly recommend checking out the advanced engineering guides at WellAlly Blog , which served as a major inspiration for this architecture. 🏗️ The Architecture: A Hybrid Vision Pipeline To achieve high accuracy, we don't just throw an image at an LLM. We use a "Segment-then-Analyze" pipeline. This ensures the LLM focuses on specific regions of interest (ROIs) rather than getting distracted by the background. graph TD A[User Uploads Food Image] --> B[Pre-processing with OpenCV] B --> C[SAM: Segment Anything Model] C --> D{Multi-Object Masking} D -->|Mask 1: Protein| E[GPT-4o Vision Reasoning] D -->|Mask 2: Carbs| E D -->|Mask 3: Veggies| E E --> F[Nutrient Mapping & Volume Estimation] F --> G[FastAPI Response: JSON Schema] G --> H[Final Dashboard] 🛠️ Prerequisites Before we start, ensure you have your environment ready: Python 3.10+ GPT-4o API Key (OpenAI) SAM Weights ( sam_vit_h_4b8939.pth ) Tech Stack : FastAPI , OpenCV , PyTorch , segment-anything 🚀 Step-by-Step Implementation 1. Object Segmentation with SAM First, we use Meta’s SAM to generate masks. This allows us to "cut out" each individual food item. import numpy as np import cv2 from segment_anything import sam_model_registry , SamPredictor # Initialize SAM sam_checkpoint = " sam_vit_h_4b8939.pth " model_type = "

2026-06-18 原文 →
AI 资讯

Consultar infracciones de tránsito en Argentina con una sola API (JSON, 33 jurisdicciones)

En una gestoría del automotor, consultar las multas de un auto era entrar a 33 sistemas distintos (Provincia, CABA, municipios), cada uno con su captcha y sus caídas. Lo automatizamos con una sola API, la de Multita , y comparto cómo quedó porque sirve a cualquiera que arme herramientas para el rubro automotor o fintech en Argentina. El problema Las infracciones de tránsito en Argentina no viven en un solo lugar. Hay sistemas provinciales (Buenos Aires, Santa Fe, Entre Ríos, Misiones, Chaco, Salta, Mendoza) y municipales (decenas). Ninguno habla con el otro. Consultar a mano son 15 a 20 minutos por vehículo. La solución: una request, todas las jurisdicciones La API de Multita recibe una patente, un DNI o un CUIT y devuelve, en JSON, las actas de cada jurisdicción con su monto y su estado. curl -X POST https://multita.com.ar/api \ -H "X-Api-Key: TU_KEY" \ -H "Content-Type: application/json" \ -d '{"tipo":"patente","valor":"AB123CD","jurisdicciones":"todas"}' { "resultados" : [ { "jurisdiccion" : "pba" , "nombre" : "Provincia de Buenos Aires" , "cantidad_actas" : 2 , "total_oficial" : 418500 }, { "jurisdiccion" : "caba" , "nombre" : "CABA" , "cantidad_actas" : 1 , "total_oficial" : 95000 } ], "resumen" : { "cantidad_actas" : 3 , "total_oficial" : 513500 } } Lo que nos ahorró Pasamos de 15-20 minutos por auto a segundos, y de cuatro ventanas abiertas a una sola llamada. Para una gestoría que cotiza decenas de carteras por día, es la diferencia entre atender 10 clientes o 30. Datos clave Cubre 33 jurisdicciones argentinas (provinciales y municipales), por patente (dominio), DNI o CUIT. Respuesta en JSON al instante; opcional, el total ya cotizado con tu pricing. Hay también una consulta web gratis para probar sin integrar nada. Si tenés una gestoría o estudio y querés esto andando sin programar, escribinos a BA Gestoría y te lo dejamos listo (y un descuento si venís de este post). Docs de la API: https://multita.com.ar/api

2026-06-18 原文 →
AI 资讯

Scheduling Without a Human Calendar

A human assistant borrows the boss's calendar; a scheduling bot owns its own. That one difference dissolves most of what makes calendar automation miserable. The borrowed-calendar model is how nearly every scheduling tool works today: connect to a person's Google or Microsoft account via OAuth, request calendar scopes, and act on their behalf. It works, but the seams show everywhere. The human's calendar fills with bookings the bot manages. Delegation permissions vary by provider and admin policy. Tokens expire when the person changes their password or leaves the company. And the bot has no address of its own — every invite, every confirmation email, appears to come from a person who didn't write it. Nylas Agent Accounts (currently in beta) invert this. Each account is a real mailbox and a real calendar , provisioned automatically, owned by your application. From a participant's perspective there's nothing special about it — it's just another attendee on the invite. What "owning availability" actually changes When the bot's calendar is its own, availability stops being a permissions question and becomes a query. The agent calls the free/busy endpoint against its own primary calendar, gets back busy blocks for a time window, and proposes open slots. No delegation, no scopes negotiation, no "the admin needs to approve calendar sharing for service accounts." The scheduling-agent tutorial wires the whole loop: a meeting request lands at scheduling@agents.yourcompany.com , a message.created webhook fires, an LLM parses duration and timezone, the agent checks its own free/busy and replies with 3 candidate slots. When the human picks one, the agent creates the event: curl --request POST \ --url "https://api.us.nylas.com/v3/grants/<GRANT_ID>/events?calendar_id=primary&notify_participants=true" \ --header "Authorization: Bearer <NYLAS_API_KEY>" \ --header "Content-Type: application/json" \ --data '{ "title": "Product demo", "when": { "start_time": 1744387200, "end_time": 174

2026-06-17 原文 →
AI 资讯

Mailboxes as Cattle: Ephemeral Email Infrastructure

When was the last time you deleted an email account on purpose? For most teams the answer is never, and that tells you something. We treat mailboxes the way we treated servers in 2008: hand-built, carefully named, kept alive indefinitely because recreating one is painful. They're pets. Meanwhile every other piece of our infrastructure — compute, queues, databases — became cattle: numbered, provisioned by code, destroyed without sentiment when the job ends. Email is finally catching up. With Nylas Agent Accounts (in beta), a mailbox is created with one call and destroyed with another, and that symmetry is the whole point. The full lifecycle in two commands Provisioning, from the CLI: nylas agent account create signup-agent@agents.yourdomain.com Or via POST /v3/connect/custom with "provider": "nylas" — no OAuth, no refresh token, just an address on a domain you've registered. Teardown is equally unceremonious: nylas agent account delete signup-agent@agents.yourdomain.com --yes (The API equivalent is a DELETE on the grant.) The signup automation recipe treats this as a loop: provision a fresh inbox, point a third-party signup form at it, catch the verification email through a message.created webhook, follow the confirmation link, delete the grant. No human inbox involved at any step, and nothing left behind. The middle of that loop is about twenty lines of webhook handler, and the recipe's version filters hard before acting — right grant, right sender, right URL shape: const { grant_id , id : messageId , from } = event . data . object ; if ( grant_id !== AGENT_GRANT_ID ) return ; const sender = from [ 0 ]?. email ?? "" ; if ( ! sender . endsWith ( " @saas-you-care-about.example.com " )) return ; const match = /https: \/\/ saas-you-care-about \. example \. com \/ confirm \? token= [^ " \s < ] +/ . exec ( message . body , ); if ( match ) await fetch ( match [ 0 ]); Nylas fires message.created within a second or two of mail arriving, so the whole signup round-trip typical

2026-06-17 原文 →
AI 资讯

The Tips Behind API Artisan: Building Laravel APIs Developers Actually Want to Use

I have just finished writing API Artisan: A Guide to Building APIs with Laravel , and I am giving it away for free. Before you commit to 300-odd pages, let me give you the short version: the tips, patterns, and small decisions that separate an API that technically works from one that developers are genuinely happy to depend on. None of this needs more hardware, a different framework, or a bigger team. It needs you to point your attention at the right things. These are the ones I keep coming back to. Start by measuring the right thing Ask most teams how they know their API is good and you get a single question back: does it work? Can I hit this endpoint and get a response? That question is necessary, and it is nowhere near enough. The question I want you to ask instead is whether your API is liveable with. Can a developer read your docs, understand your auth model, make a successful request, and handle an error without contacting support, trawling a forum, or guessing what a status code is trying to tell them? The gap between "works" and "liveable with" never shows up in a sprint retro, but it shows up everywhere else: in support volume, in integration timelines that overrun, and in the quiet moment a developer decides to build around your API rather than with it. Everything else in the book hangs off one mindset shift: an API is a product. It has users. Treat it as an implementation detail and it will behave like one. It will change without warning when your internals change, and it will be inconsistent because different people wrote different parts on different days with different conventions. Write the contract before the code The natural way to build an endpoint is to write the handler, return some data, and document it afterwards if there is time. It feels efficient, and in the short term it is. The problem is what it produces: a contract that was never designed, only discovered. Let me show you the trap, because I have watched it catch good developers. You have

2026-06-17 原文 →
AI 资讯

The 5-Minute Mailbox

The email mailbox just became an API resource, and that matters far more than the setup time it saves. For most of software history, a real email address — one that sends, receives, and threads — was an artifact of IT process. Someone created it in an admin console, someone else configured the client, and your application got access through OAuth consent screens and refresh tokens borrowed from a human. Compare that to how you get a database, a queue, or a TLS cert today: one API call, one ID back, done. Nylas Agent Accounts (currently in beta) close that gap. The quickstart goes from API key to a sending-and-receiving mailbox in under 5 minutes, and the provisioning step is a single request: curl --request POST \ --url "https://api.us.nylas.com/v3/connect/custom" \ --header "Authorization: Bearer <NYLAS_API_KEY>" \ --header "Content-Type: application/json" \ --data '{ "provider": "nylas", "settings": { "email": "test@your-application.nylas.email" } }' No refresh token, no OAuth dance — unlike OAuth providers, the "nylas" provider needs only an email address on a registered domain. The response contains a grant_id , and that one ID drives everything else: messages, drafts, threads, folders, attachments, calendar, webhooks. There are actually three ways to create an account — this API call, the Dashboard, or a single CLI command ( nylas agent account create ) — but they all end at the same place: a live mailbox. Why 5 minutes is a threshold, not a convenience Provisioning time isn't a linear cost. There's a threshold below which a resource changes category — from "thing you request" to "thing your code creates." Virtual machines crossed it with cloud APIs and we got autoscaling. TLS certs crossed it with ACME and we got HTTPS-by-default. Mailboxes crossing it means email addresses stop being scarce, pre-planned identities and start being something a program allocates when it needs one. What does that look like in practice? System mailboxes without ceremony. A support

2026-06-17 原文 →