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

标签:#API

找到 307 篇相关文章

AI 资讯

Stop Writing Boilerplate API Responses: Meet BaR-js

We've all been there: you’re building an endpoint, and for the hundredth time, you’re typing out res.status(200).json({ success: true, data: ... }) . It feels repetitive, and honestly, it’s a recipe for inconsistency across your API. I wanted to fix that, so I built BaR-js . What is it? BaR (Builder a Response) is a lightweight, framework-agnostic TypeScript library designed to help you serve API responses like a pro—almost like a bartender mixing a drink. It strips away the JSON clutter and ensures every response you send follows a consistent, production-ready schema. Why use it? Consistency: Every endpoint speaks the same language. Fluent API: You can use a chainable syntax like res.builder.as.ok(data) instead of manually crafting objects every time. Traceability: It automatically handles request_id and timestamps, making debugging so much easier. Type Safety: Built with strict TypeScript, so you get great IntelliSense support. It’s this simple: import express from ' express ' ; import { BarExpressAdapter } from " @vorlaxen-labs/bar-js " ; const app = express (); // 1. Configure the adapter const bar = new BarExpressAdapter ({ environment : ' production ' , logger : console , }); // 2. Register it as middleware // This injects `res.builder` and `req.bar` into every route! app . use ( bar . handler ()); // Now you can use it in any route app . get ( ' /user ' , ( req , res ) => { return res . builder . as . ok ({ name : ' John ' }). build (); }); Why "BaR"? I like the idea that "your code is a work of art, and your responses are its signature." The clearer your response schema, the more professional and valuable your API feels to whoever is consuming it. The project is still fresh, and I’d love to hear what you think. If you’re looking to clean up your API layer, give it a spin! Feedback, issues, or PRs are more than welcome. Check it out on GitHub: https://github.com/vorlaxen-labs/bar-js Grab it from NPM: https://www.npmjs.com/package/@vorlaxen-labs/bar-js Cheers!

2026-06-15 原文 →
AI 资讯

3- AWS Serverless: REST API vs. HTTP API

There is common point of confusion. what's the different between REST API vs. HTTP API in AWS and what's the different between them and a traditional Rest API you write with e.g express in node in the broader software world, a "REST API" is just an architectural pattern built on top of HTTP requests. The confusion comes entirely from AWS-specific marketing terminology . When you are inside the AWS ecosystem, Amazon API Gateway is a specific managed service, and AWS chose to split that service into two different flavors (or software products): one called "REST API" and one called "HTTP API." Here is exactly how they work under the hood, how they differ internally, and how it compares to traditional servers. 1. How It Works: REST API vs. HTTP API (AWS Architecture) Think of Amazon API Gateway as a reverse proxy or a "front door" that sits in front of your Lambda functions. AWS REST API (The Heavyweight) When a request hits an AWS REST API, AWS passes that request through a massive feature pipeline before it ever touches your Lambda code. [Client Request] ──> [Authentication (Cognito/IAM)] ──> [Request Validation] ──> [Data Transformation (VTL)] ──> [Your Lambda] What happens: AWS decrypts the request, validates the JSON schema, checks API keys, runs any custom request transformations using a complex mapping language called VTL, and then invokes your Lambda function. Why it costs more: You are paying AWS for all that computing power happening inside the API Gateway layer itself. AWS HTTP API (The Express Lane) When a request hits an AWS HTTP API, AWS strips out almost the entire middle pipeline. [Client Request] ──> [JWT/OAuth2 Authorization Only] ──> [Your Lambda] What happens: The HTTP API acts as a lightning-fast router. It optionally checks a standard JWT token, converts the incoming HTTP request directly into a clean JSON object, and throws it straight into your Lambda function. Why it costs less: Because AWS is doing almost zero processing or data manipulation. Y

2026-06-15 原文 →
AI 资讯

Why deemed-export law breaks frontier model APIs

So you built your stack on a hosted frontier model. Good throughput, clean API, your foreign-national engineers hit the same endpoint as everyone else. Then on June 12 the US government pulled Claude Fable 5 and Mythos 5 offline for the entire planet, three days after launch, and the reason is a compliance gap baked into how these things actually serve traffic. Here's the thing worth understanding as an engineer: the bug was narrow. The takedown wasn't. The gap between those two facts is where every team running a hosted model should be paying attention. What actually triggered it Commerce hit Anthropic with an order barring access to both models by any foreign national, anywhere, inside or outside the US, including Anthropic's own foreign-national staff. The stated trigger was a jailbreak: point the model at a codebase, ask it to find flaws. That's it. Anthropic reviewed the demo and watched it surface a handful of already-known minor vulns, the kind GPT-5.5 and other public models hand you with no bypass at all. So the capability wasn't exotic. It was automated code review on a Tuesday. The reason it went nuclear is the legal layer sitting on top, not the finding itself. The architecture problem: you can't gate on a passport you can't see Walk it through like any other access-control question. The restriction names a class of users: foreign nationals. Every one of them, globally. Now look at what a model API knows about a session at request time. restriction: deny any foreign national, anywhere session metadata: auth token, IP, usage tier NOT in session: verified nationality isolatable set: ∅ only compliant state: serve nobody An API session doesn't carry a verified passport. IP geolocation is trivially defeated by a VPN and tells you location, not citizenship anyway. There's no field in the request that maps to the restricted class. When you can't isolate the users you're forbidden to serve, the only provably-compliant state is serving no one. Off switch. Global.

2026-06-14 原文 →
AI 资讯

Restricting Attachments in Agent Inboxes

Three fields on a policy decide which attachments ever reach your email agent: { "name" : "Locked-down agent inbox" , "limits" : { "limit_attachment_size_limit" : 26214400 , "limit_attachment_count_limit" : 20 , "limit_attachment_allowed_types" : [ "application/pdf" , "image/png" ] } } Size (that's 25 MB in bytes), count per message, and an allowlist of MIME types. POST that to /v3/policies , attach the resulting policy_id to a workspace, and every Agent Account in the workspace enforces it on inbound mail from then on. Why an autonomous reader needs this more than you do When a human gets a suspicious attachment, there's a judgment step: weird sender, weird filename, don't open it. An email agent has no such instinct unless you build one — and the agents most worth building are exactly the ones that process attachments: parsing invoices, extracting resumes, reading shipped documents. That processing step is the attack surface. A hostile PDF aimed at your parser, a 10,000-page document aimed at your token budget, a zip bomb aimed at your storage — all of them arrive the same way legitimate input does. You can defend in application code, but then every consumer of the mailbox has to get it right, forever. Policy limits on Nylas Agent Accounts (a beta feature) enforce the constraint at the mailbox itself, before any of your code runs. One clarification that saves a support ticket: inbound rules can't do this job. Rules match on sender fields — from.address , from.domain , from.tld — and know nothing about what a message carries. Attachment control lives on the policy, and only there. From policy to enforced, end to end The policy applies through a workspace, not directly to a grant. The full wiring is three calls. Create the policy at /v3/policies , set it as the workspace's policy_id (a PATCH /v3/workspaces/{workspace_id} if the workspace already exists), then create the account into that workspace: curl --request POST \ --url "https://api.us.nylas.com/v3/connect/cus

2026-06-14 原文 →
AI 资讯

Running Chinese LLMs at Scale: A Cloud Architect's Notes

Running Chinese LLMs at Scale: A Cloud Architect's Notes I want to talk about something I've been wrestling with on real production workloads: the four Chinese model families — DeepSeek, Qwen, Kimi, and GLM — and how they actually behave when you wire them into a multi-region pipeline serving thousands of requests per second. I've spent the last several months routing traffic across all four through Global API's unified endpoint, and the picture that emerged was messier and more interesting than any benchmark table would have you believe. Most comparisons you'll find online are written by people who ran a handful of prompts in a notebook. I'm not that person. I care about p99 latency, failover behavior, what happens when a region goes down at 3 AM, and whether the model that wins on a leaderboard also wins when 500 concurrent users hit it simultaneously. Let me walk you through what I actually found. Why These Four, And Why Through One Endpoint Before I dive in, a quick word on routing. I've been burned before by model lock-in and vendor-specific quirks, so when I started this evaluation I refused to scatter my SDK calls across four different providers. Global API gives me a single OpenAI-compatible base URL ( https://global-apis.com/v1 ), one auth pattern, and the freedom to A/B test models without rewriting client code. If you architect anything at scale, you already know this is non-negotiable. The four families above are the ones I kept coming back to because each one claimed a different crown — and I needed to know which crown was real. The High-Level Matrix Here's the snapshot I keep pinned to my team's dashboard. It's not pretty, but it's honest: DeepSeek — $0.25 to $2.50/M output. The V4 Flash at $0.25/M is the workhorse. Qwen — $0.01 to $3.20/M output. Widest spread of any family. Alibaba's offering. Kimi — $3.00 to $3.50/M output. Premium-only, and they charge for it. GLM — $0.01 to $1.92/M output. From Zhipu. Big swing in capability across tiers. All four

2026-06-14 原文 →
AI 资讯

OpenAI-Compatible Base URL Troubleshooting: 7 Checks Before You Blame the SDK

An OpenAI-compatible base URL is supposed to make model switching boring: change the endpoint, keep the SDK, and move on. In real projects, the first run often fails with a 401 , 404 , 429 , or a model-not-found error. Here is the checklist I use before blaming the SDK. 1. Confirm the base URL includes the right API prefix Most OpenAI-compatible gateways expect a /v1 prefix: from openai import OpenAI client = OpenAI ( api_key = " YOUR_RELAY_KEY " , base_url = " https://api.wappkit.com/v1 " , ) If you use only the domain, some SDK calls may resolve to the wrong path. Check the provider's docs and copy the exact base URL format. 2. Make sure the key belongs to that gateway A common mistake is mixing keys: OpenAI key with relay base URL Relay key with OpenAI base URL Old test key from a disabled project Key copied with a leading or trailing space When you see 401 Unauthorized , print the first and last few characters of the key locally and compare it with the dashboard. Do not log the full key. 3. Check the model name from the live list Do not guess model names from memory. Gateway model names can change as upstream availability changes. Before using gpt-5.5 , gpt-5.4 , or a Claude Code model, check the current model list . Copy the model id exactly. resp = client . chat . completions . create ( model = " gpt-5.5 " , messages = [{ " role " : " user " , " content " : " Say hello in one sentence. " }], ) If the model name is wrong, you usually get 404 , model_not_found , or a gateway-specific validation error. 4. Test with the smallest possible request Before debugging your whole app, run one tiny request: resp = client . chat . completions . create ( model = " gpt-5.5 " , messages = [{ " role " : " user " , " content " : " ping " }], max_tokens = 20 , ) print ( resp . choices [ 0 ]. message . content ) If this works, the base URL, key, and model are probably fine. Your bug is likely in the app layer: streaming, tool calling, message format, proxy settings, or retry logi

2026-06-14 原文 →
AI 资讯

Claude Fable 5 Pulled by US Export Order — 72 Hours After Launch

Three days. Claude Fable 5 — Anthropic's most capable model ever shipped to the public, posting 95% on SWE-bench Verified — was live for exactly 72 hours before the US government issued an export control directive on June 12 that forced Anthropic to pull it globally. For everyone. Including US users. Including Anthropic employees who hold foreign passports. Here is what Fable 5 actually is, what the government directive says, what Anthropic says about it, and what developers building on Claude should do while this gets resolved. What Claude Fable 5 Is Anthropic launched Claude Fable 5 on June 9, 2026, alongside Claude Mythos 5, its restricted sibling for government-adjacent cybersecurity work. Fable 5 is the first publicly available model in Anthropic's new "Mythos-class" tier — a category above the previous frontier that Claude Opus 4.8 (released May 28) occupied. The benchmark gap is not close. Fable 5 posted 95.0% on SWE-bench Verified and 80.3% on SWE-bench Pro. The next best competitor on SWE-bench Pro is GPT-5.5, sitting at 58.6%. That is a 21.7-point gap — roughly twice the margin by which Claude Opus 4.8 led its generation. Across all eight coding benchmarks Anthropic published at launch, Fable 5 led with an average margin of 11.8 points: Benchmark Claude Fable 5 Next Best Gap | SWE-bench Verified | 95.0% | ~74% | +21 | | SWE-bench Pro | 80.3% | 58.6% (GPT-5.5) | +21.7 | | FrontierCode Diamond | leads | baseline | +23.6 | | HLE (no tools) | leads | baseline | +13.7 | | Terminal-Bench | leads | baseline | +4.6 | Beyond static benchmarks, Anthropic ran a long-horizon game-playing evaluation using Slay the Spire with persistent file-based memory. Fable 5 improved three times faster than Opus 4.8 as memory accumulated, and reached the final act three times as often. The large-context reasoning advantage — the same capability that powered the 8x engineering productivity multiplier at Anthropic — is structurally more pronounced in Fable 5 than in any previous publ

2026-06-14 原文 →
AI 资讯

Track Email Opens From Your Agent's Outreach

You built an outreach agent, it sent 80 follow-ups this week, and you have no idea what happened to any of them. Did the prospect open the message? Click the demo link? Is the silence a "no" or a spam-folder problem? Without engagement signals, your agent is firing into the void and your follow-up logic is guesswork. The fix has two parts: turn tracking on when you send, and subscribe to the webhooks that report what recipients do. Tracking starts at send time, not after Opens, clicks, and replies are only reported for messages sent with tracking enabled — you can't retroactively track a message that's already out. On the Send Message request, pass a tracking_options object with three booleans plus an optional label that gets echoed back in every notification: curl --request POST \ --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages/send' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer <NYLAS_API_KEY>' \ --data-raw '{ "subject": "Quick follow-up on your trial", "body": "Thanks for trying us out. Reply or <a href=\"https://example.com/demo\">book a demo</a> when ready.", "to": [{ "name": "Kim Townsend", "email": "kim@example.com" }], "tracking_options": { "opens": true, "links": true, "thread_replies": true, "label": "trial-followup-q2" } }' The label is the piece agents should lean on: stamp it with your campaign ID or contact ID and every later notification carries it, so your handler matches events back to outreach state without storing a message-ID mapping. One caveat before you test: message tracking needs a production application — trial accounts get "Tracking options are not allowed for trial accounts" back. Three triggers, one endpoint Engagement events arrive over webhooks. Subscribe one HTTPS endpoint to all three triggers — message.opened , message.link_clicked , and thread.replied : curl --request POST \ --url 'https://api.us.nylas.com/v3/webhooks/' \ --header 'Content-Type: application/json' \ --header 'Autho

2026-06-14 原文 →
AI 资讯

Async APIs: The 202 Accepted + Polling Pattern for Long-Running Operations

Some API requests can't finish in time for a single HTTP response. Generating a report, transcoding a video, running a batch import — these take seconds or minutes, far longer than any client should hold a connection open for. If you try to do this work inside a normal request, you'll hit gateway timeouts, frustrated clients retrying half-finished jobs, and load balancers killing connections at 30 or 60 seconds. The fix is a well-established HTTP pattern: accept the work, hand back a receipt, and let the client poll for the result. Here's how to build it properly. The shape of the pattern The client POST s the job. The server validates it, enqueues it, and immediately returns 202 Accepted with a URL where the status lives. The client polls that status URL until the job is done (or failed ). When complete, the status response points to the finished resource. The key detail most implementations get wrong: 202 does not mean "success." It means "I accepted this and will work on it." The actual outcome arrives later. Step 1: Accept the job import express from " express " ; import { randomUUID } from " crypto " ; const app = express (); app . use ( express . json ()); const jobs = new Map (); // use Redis or a DB in production app . post ( " /v1/reports " , ( req , res ) => { const id = randomUUID (); jobs . set ( id , { status : " pending " , createdAt : Date . now (), result : null }); // Kick off work without blocking the response processReport ( id , req . body ). catch (( err ) => { jobs . set ( id , { status : " failed " , error : err . message }); }); res . status ( 202 ) . location ( `/v1/reports/ ${ id } ` ) . json ({ id , status : " pending " }); }); Notice the Location header. It tells the client exactly where to look — no need to construct the URL itself. Step 2: Expose a status endpoint app . get ( " /v1/reports/:id " , ( req , res ) => { const job = jobs . get ( req . params . id ); if ( ! job ) return res . status ( 404 ). json ({ error : " unknown job " })

2026-06-14 原文 →
AI 资讯

How API Testing Levelled Up My QA Career (And Why Most Engineers Skip It)

The Moment I Realised UI Testing Wasn't Enough Three years into my QA career, I thought I was doing well. I had a solid Selenium suite running. Regression coverage was green. Stakeholders were happy. Then a production incident happened. A payment API was returning incorrect amounts under a specific condition. The UI looked perfect — amounts displayed correctly after rounding. But the raw API response? Off by a significant margin. My entire test suite missed it. Every single test. Because I was only testing what users saw . Not what the system was actually doing . That incident changed how I approached QA forever. 👇 Why API Testing Is the Most Underrated Skill in QA Let me be direct about something. Most QA engineers treat API testing as a secondary skill. Something you do with Postman when a developer asks you to verify an endpoint. A quick sanity check before moving on. That's the wrong mental model entirely. Here's the truth after 7.5 years: The API layer is where your product actually lives. The UI is a presentation layer. It shows users a version of the truth. But the API? That's the truth itself. Data contracts, business logic, validation rules, error handling — all of it lives at the API layer. If you're only testing the UI, you're testing the packaging. Not the product. My API Testing Journey — Tool by Tool Let me walk you through exactly how my API testing practice evolved, and what each tool actually taught me. Stage 1 — Postman: Learning to Think in Requests Postman was my entry point. And it's still the tool I reach for first when exploring a new API. But most people use Postman wrong. They treat it like a manual testing tool — fire a request, check the response, move on. That's wasting 80% of what Postman can do. Here's how I actually use it: Collections + Environments = your real power combo // Environment variables — not hardcoded values {{ base_url }} /api/ v1 / users / {{ user_id }} // Switch between dev/staging/prod by changing one environment // No

2026-06-14 原文 →
AI 资讯

How a PHP SDK Can Save You Hundreds of Lines of API Integration Code

How a PHP SDK Can Save You Hundreds of Lines of API Integration Code Most APIs provide documentation, examples, and maybe even a Postman collection. That's usually enough to get started. But once your application grows, you'll quickly discover that working directly with HTTP requests introduces a surprising amount of repetitive code. You end up writing the same things over and over: Authentication headers Request serialization Response parsing Error handling Pagination logic DTO mapping This is exactly why SDKs exist. In this article, we'll look at how a PHP SDK can simplify API integrations and reduce maintenance costs over time. The Hidden Cost of Direct API Calls Let's imagine you're integrating a URL shortening API. A typical implementation might look like this: $client = new GuzzleHttp\Client (); $response = $client -> post ( 'https://example.com/api/links' , [ 'headers' => [ 'X-Api-Key' => $apiKey , 'Content-Type' => 'application/json' , ], 'json' => [ 'url' => 'https://example.com' ] ] ); $data = json_decode ( $response -> getBody () -> getContents (), true ); This doesn't seem bad. Now repeat it for: Create link Update link Delete link Get link List links Create group Update group Get profile Eventually your codebase becomes filled with API boilerplate. The business logic becomes harder to see because it's buried under HTTP implementation details. What a Good SDK Does A well-designed SDK abstracts repetitive tasks and exposes a clean programming interface. Instead of dealing with HTTP requests directly, developers work with resources and objects. For example: $link = $client -> links () -> create ([ 'url' => 'https://example.com' ]); This is easier to read and easier to maintain. The SDK becomes responsible for: Authentication Request building Validation Serialization Response mapping Exception handling Consistent Error Handling One common problem with raw API integrations is inconsistent error handling. Without an SDK, every request may need its own validat

2026-06-13 原文 →
AI 资讯

Why Most Sports Betting Projects Fail Before Launch (And It's Not the Algorithm)

If you've ever tried building a sports betting application, odds tracker, arbitrage scanner, value betting tool, or sports analytics dashboard, you've probably experienced the same thing: You start with the exciting part. The idea. The algorithm. The UI. The business logic. And then reality hits. The Hidden Problem Nobody Talks About Most developers assume the hardest part of a betting-related project is the prediction model or arbitrage logic. In practice, the real challenge is data infrastructure. Before your project can calculate anything, you need: Live events Accurate odds Multiple bookmakers Consistent market structures Historical updates Reliable refresh rates And suddenly your "weekend project" turns into a full-time data engineering job. The Scraping Trap Most developers begin by scraping bookmaker websites. At first it seems simple: Open DevTools Find the API request Parse the response Save the data Done, right? Not quite. Within a few weeks you'll likely encounter: Changed endpoints Rate limits Cloudflare protection Different JSON formats Missing markets Broken parsers Increased maintenance costs Instead of improving your product, you're fixing scrapers. Again. And again. And again. Every Bookmaker Speaks a Different Language Let's say you want to compare odds from five sportsbooks. You quickly discover that every provider structures data differently. One bookmaker might return: { "home" : "Liverpool" , "away" : "Arsenal" } Another might return: { "team1" : "Liverpool" , "team2" : "Arsenal" } A third one could use: { "participants" : [ "Liverpool" , "Arsenal" ] } Now multiply that problem across: dozens of bookmakers hundreds of leagues thousands of events You end up spending more time normalizing data than building features. Real-Time Data Changes Everything Many projects work perfectly during testing. Then live data arrives. Odds can move multiple times within a minute. If your system refreshes too slowly: arbitrage opportunities disappear alerts become

2026-06-13 原文 →
AI 资讯

USPS Just Broke Your Magento Shipping. Here's the Fix.

If your Magento store still depends on the old USPS Web Tools integration, you should assume your shipping rates are either already broken or one change away from breaking. That sounds dramatic, but it is the practical reality we have been seeing. USPS has moved away from the old Web Tools model and toward REST API v3 with OAuth 2.0 authentication. Magento's legacy USPS integration was built for a different era. For merchants, the symptom is simple: rates stop showing up, return inconsistently, or fail under conditions you did not use to worry about. For Magento developers, the reason is also simple: the built-in carrier module is not designed for the current USPS authentication and request model. This article explains what changed, why core Magento falls over here, how to migrate cleanly, and what to watch for whether you choose an extension or a custom build. What changed: USPS Web Tools is not the same platform anymore Historically, Magento's USPS integration talked to Web Tools-style USPS endpoints: structured shipping requests, legacy authentication, and XML responses. That is not the model USPS wants merchants using now. The modern USPS stack is based on: REST API v3 endpoints OAuth 2.0 for authentication Different request and response payloads Different onboarding and credential management patterns That shift matters because it is not just a URL update. It changes authentication, token handling, and request structure. In practical terms, a migration now means: Getting the right USPS developer credentials Exchanging those credentials for OAuth access tokens Updating the carrier request layer to use REST payloads Mapping the new response format back into Magento shipping methods If you skip any of that and try to "patch" the old module with endpoint changes, you are going to waste time. Why Magento 2's built-in USPS module no longer works Magento's built-in USPS module was not architected around OAuth-backed REST API calls. It expects a legacy carrier contract

2026-06-13 原文 →
AI 资讯

Um resumo sobre o padrão de segurança HMAC

Definição O HMAC (Hash-based Message Authentication Code) é um mecanismo de segurança que permite verificar a integridade e autenticidade de uma mensagem, garantindo que ela não foi alterada e que foi gerada por quem possui uma chave secreta. Ele é muito usado em autenticação de APIs, tokens e assinaturas digitais. Analogia Imagine que você envia uma carta dentro de um envelope lacrado com um selo exclusivo que só você e o destinatário conhecem a forma de produzir. Se alguém abrir a carta e alterar qualquer palavra, o selo não vai mais bater com o original. O HMAC funciona exatamente assim: ele “lacra” os dados com uma assinatura impossível de reproduzir sem a chave secreta. Exemplo sem HMAC (inseguro) $payload = [ 'user' => 'joao' , 'exp' => time () + 300 ]; // token simples sem proteção $token = base64_encode ( json_encode ( $payload )); Problema Qualquer pessoa pode: decodificar o token alterar exp reencodar e enganar o sistema Exemplo com HMAC (seguro) $payload = [ 'user' => 'joao' , 'exp' => time () + 300 ]; $secret = 'chave_super_secreta' ; $signature = hash_hmac ( 'sha256' , json_encode ( $payload [ 'user' ]) . '|' . $payload [ 'exp' ], $secret ); $payload [ 'sig' ] = $signature ; $token = base64_encode ( json_encode ( $payload )); Validação do lado do servidor $payload = json_decode ( base64_decode ( $_GET [ 'token' ]), true ); $check = hash_hmac ( 'sha256' , json_encode ( $payload [ 'user' ]) . '|' . $payload [ 'exp' ], $secret ); if ( ! hash_equals ( $check , $payload [ 'sig' ])) { die ( "Token inválido" ); }

2026-06-13 原文 →
AI 资讯

Migrating From Transactional Email to Agent Accounts

This is what most agent email code looks like today: // SendGrid / Resend / Postmark — outbound only await sendgrid . send ({ to : " prospect@example.com " , from : " outreach@yourcompany.com " , subject : " Following up on your demo request " , html : " <p>Hi Alice — wanted to follow up on...</p> " , }); // That's it. If Alice replies, the agent never sees it. The send works fine. The problem is everything after: when Alice replies, that reply bounces, lands at a no-reply nobody reads, or hits a human inbox the agent can't reach programmatically. The agent is talking into a void. Transactional providers were built for receipts and password resets — one-way mail — and an agent that's supposed to hold a conversation needs a receive path those APIs simply don't have. Agent Accounts (a beta feature from Nylas) close that gap with a full hosted mailbox: send and receive, with threading, webhooks, and folders built in. Here's what the migration actually involves. The delta, honestly Outbound barely changes — it's still an API call. The new parts are everything transactional providers never gave you: Concern Transactional provider Agent Account Outbound API call Same — POST /messages/send Inbound None (or polling a shared inbox) Replies land automatically, fire message.created Threading You track Message-ID yourself Headers preserved, threads grouped automatically Reply detection Parse forwards, poll Webhook within seconds of arrival DNS SPF/DKIM/DMARC for the provider MX, SPF, DKIM, DMARC for the mailbox host Provision the mailbox One call creates the account; the response includes a grant_id that identifies it on every later 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": "outreach@agents.yourcompany.com" } }' (Or nylas agent account create outreach@agents.yourcompany.com from the CLI.) C

2026-06-12 原文 →
AI 资讯

Hurl vs Postman: Git-Friendly API Testing With Proxy-Aware Egress (2026)

TL;DR: You'll learn how to replace Postman collections with plain-text Hurl files that live in Git, run in CI, and test your API’s geo behavior from any country. Debugging API issues always boils down to taking the tests you already have, running them from a different network or region, and comparing what your API receives. But I bet most of us can’t actually do that right away because our test infrastructure itself is fragmented. Your CI could be using a different config entirely from the “correct” one on a local dev machine, and half the collections may still point to a staging URL that changed months ago. Postman doesn’t produce diff-friendly artifacts, so even figuring out what changed is a full-on investigation. If any of that sounds familiar, I’d recommend finally taking the big step and replacing your Postman collection with Hurl — a command-line HTTP test runner where tests are plain **.hurl** text files that live in Git. For this tutorial, I’ll also walk you through multi-region testing — how to run those tests using a proxy to get a German egress IP, and see what the API actually returns from there. Everything below is self-contained, you’ll only need a new Git repo, then create the tests (three plaintext files.) The Test Suite at a Glance Create a folder (name it whatever you like — hurl-api-tests works) and these are the files we're going to be creating at its root . That folder is your Git repo root; paths in commands and CI are relative to it. Note how we’re using multiple .env files. If you're new to API testing, you'll find out why in a bit. hurl-api-tests/ ├── tests/ │ ├── health.hurl # smoke test -- Makes sure Hurl works, basic asserts. Skip if you want │ ├── auth-flow.hurl # Tests chaining + jsonpath capture + Bearer header │ └── geo-detail.hurl # Tests two egress profiles, real country/ASN diff (direct or proxied) ├── .env.local.example ├── .env.ci.example ├── .env.proxy-de.example ├── run-tests.mjs # cross-platform runner └── .github/workflows/a

2026-06-12 原文 →
AI 资讯

KI-Agent Tool-Aufrufe mit Apidog testen: Vor Produktionsausfällen

Ein KI-Agent ist nur so zuverlässig wie die APIs, die er aufruft. Das Modell wählt ein Tool aus, füllt Argumente ein und sendet eine Anfrage. Wenn diese Anfrage fehlschlägt, die falsche Form zurückgibt oder hängen bleibt, trifft Ihr Agent eine selbstbewusste Entscheidung auf Basis schlechter Daten. Produktions-Agenten stehen und fallen deshalb mit einer getesteten Tool- und API-Schicht. Apidog noch heute ausprobieren Diese Anleitung zeigt, wie Sie einen Agenten erstellen, der reale Tools aufruft, und wie Sie Apidog als API-Schicht und Testumgebung verwenden. Sie definieren Tool-Endpunkte, mocken sie für die Offline-Entwicklung und schreiben Assertions, die fehlerhafte Tool-Aufrufe abfangen, bevor sie Benutzer erreichen. Was ein Agent auf der API-Ebene tatsächlich tut Reduziert auf die technische Schleife passiert Folgendes: Das Modell erhält ein Benutzerziel und eine Liste verfügbarer Tools. Es gibt einen Tool-Aufruf zurück: Tool-Name plus JSON-Argumente. Ihr Code führt den Aufruf aus, meist als HTTP-Request. Das API-Ergebnis geht zurück an das Modell. Das Modell ruft ein weiteres Tool auf oder antwortet dem Benutzer. Die kritischen Fehler entstehen fast immer in Schritt 3 und 4: Das Modell halluziniert ein Argument. Die API gibt 400 , 422 , 429 oder 500 zurück. Das Antwortschema hat sich geändert. Der Request läuft in ein Timeout. Eine Ratenbegrenzung greift mitten in der Agenten-Schleife. Wenn Sie KI-Agenten als neue API-Konsumenten betrachten, wird klar: Ihr Agent ist ein API-Client. Er braucht dieselbe Teststrenge wie jeder andere produktive Client. Die Arbeit besteht aus zwei Teilen: Tools als reale, testbare API-Operationen definieren. Prüfen, ob der Agent diese Tools unter guten und schlechten Bedingungen korrekt aufruft. Schritt 1: Tools als reale API-Operationen entwerfen Definieren Sie jedes Tool zuerst als API-Endpunkt in Apidog. Behandeln Sie Tool-Schema und API-Schema als denselben Vertrag. Beispiel: Tool: get_weather API-Operation: GET /weather Paramet

2026-06-12 原文 →
AI 资讯

One Agent Identity Per Customer: Multi-Tenant Email

Provisioning a tenant-scoped email identity for your SaaS is one POST: 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", "workspace_id": "<WORKSPACE_ID>", "settings": { "email": "scheduling@customer-a.com" } }' No OAuth dance, no refresh token — just an address on a registered domain. The response comes back already valid: { "request_id" : "5967ca40-a2d8-4ee0-a0e0-6f18ace39a90" , "data" : { "id" : "b1c2d3e4-5678-4abc-9def-0123456789ab" , "provider" : "nylas" , "grant_status" : "valid" , "email" : "scheduling@customer-a.com" , "scope" : [], "created_at" : 1742932766 } } The data.id is a grant_id that works with every existing Nylas endpoint, and the account is live immediately. That's the primitive behind a multi-tenant pattern worth knowing: one Agent Account per customer, on each customer's own verified domain, all managed from a single application. (Agent Accounts are in beta, so the surface may shift before GA.) The architecture in one paragraph Your app runs scheduling@customer-a.com , scheduling@customer-b.com , and so on — same code path, different identities. Each account has its own policy, its own send quota, and its own sender reputation. A single application can manage accounts across an unlimited number of registered domains, so tenant count is a billing question, not an architectural one. Customer A's deliverability problems stay Customer A's; nothing they do contaminates Customer B's mail. Domains: register once, mint accounts forever The provisioning docs lay out two domain strategies you can mix freely in one application: Strategy Address format Setup Trial domain alias@<your-application>.nylas.email None — instant Your own domain alias@yourdomain.com MX + TXT records at the DNS provider For the per-customer pattern, each tenant brings their domain. You register it once per organization (picking the US

2026-06-12 原文 →
AI 资讯

Extract OTP Codes From Email, Automatically

What does your automation do when the login flow it's driving sends a six-digit code instead of a confirmation link? For most teams the honest answer is "a human goes and checks a shared inbox," which is a strange bottleneck to leave in the middle of an otherwise fully automated pipeline. There's a cleaner shape: the agent owns the mailbox the code lands in. With a Nylas Agent Account — a hosted mailbox controlled entirely through the API, currently in beta — the OTP email arrives, a webhook fires, your handler extracts the code, and whatever orchestrates the login gets it back. No human, no inbox-checking Slack message, no screen-scraping Gmail. Step one: make sure it's the right email A message.created webhook fires on every inbound message, so the first job is filtering down to the one that actually carries the code. The recipe uses two signals together — sender domain and a subject heuristic: app . post ( " /webhooks/otp " , async ( req , res ) => { res . status ( 200 ). end (); const event = req . body ; if ( event . type !== " message.created " ) return ; const msg = event . data . object ; if ( msg . grant_id !== AGENT_GRANT_ID ) return ; const sender = msg . from ?.[ 0 ]?. email ?? "" ; const subject = msg . subject ?? "" ; const senderMatches = sender . endsWith ( " @no-reply.example.com " ); const subjectLooksRight = /code|verif|one. ? time|passcode/i . test ( subject ); if ( ! senderMatches || ! subjectLooksRight ) return ; await handleOtp ( msg . id ); }); Neither check alone is enough. Sender-only matching trips on welcome emails from the same domain; subject-only matching trips on anything that mentions "verification." Regex first, LLM second Most OTP emails follow one of a few shapes: a standalone 4–8 digit number, or a code after a label like "Your code is:". Three patterns, tried in order from most to least specific, cover the vast majority of services: const patterns = [ / (?: code|passcode|one [\s - ]? time )[^\d]{0,20}(\d{4,8}) /i , // "Your code

2026-06-12 原文 →
AI 资讯

Ephemeral Inboxes: Spin Up a Mailbox Per Test Run

Two CI workers kick off at the same moment. Both sign up a test user, both poll the shared QA Gmail account for "the" verification email, and worker #7 grabs the message that belonged to worker #12. The test passes. The wrong test. You spend an afternoon staring at a green build that should've been red. Shared inboxes are the single biggest source of flakiness in email-dependent E2E tests, and every workaround — catch-all forwarding rules, label rules scoped per PR, OAuth tokens living on the runner — adds another moving part that breaks on its own schedule. The fix is structural: every test gets its own address, on infrastructure your suite provisions and destroys. One wildcard, infinite addresses The E2E email testing recipe sets this up with one CLI command: nylas inbound create e2e You get back an inbox ID and a wildcard pattern shaped like e2e-*@yourapp.nylas.email . From there, each test mints a unique address under the wildcard — e2e-<uuid>@yourapp.nylas.email — and there's nothing to provision per address. You don't pay or configure per address either; the wildcard is just a convention, so burn UUIDs freely. Mail flows through MX records hosted on the Nylas side, which means zero DNS work in your own zone (the tradeoff: addresses live under *.nylas.email ). The Playwright fixture is two pieces — an address minter and a poller: export const test = base . extend < Fixtures > ({ testEmail : async ({}, use ) => { await use ( `e2e- ${ randomUUID ()} @yourapp.nylas.email` ); }, pollInbox : async ({ testEmail }, use ) => { const poll = async ( timeoutMs = 30 _000 ) => { const deadline = Date . now () + timeoutMs ; while ( Date . now () < deadline ) { const out = execSync ( `nylas inbound messages ${ process . env . INBOX_ID } --json --limit 50` , ). toString (); const match = JSON . parse ( out ). find (( m ) => m . to . some (( t ) => t . email === testEmail ), ); if ( match ) return match ; await new Promise (( r ) => setTimeout ( r , 1500 )); } throw new Error (

2026-06-12 原文 →