One-time codes and links
Most sign-up and password-reset tests want one of two things out of a message: the six digits, or the link. Writing the regular expression for that in every project is busywork, so the API does it:
GET /subscriptions/{sid}/messages/{id}/extract
Same authentication and the same 404 rules as reading the message itself.
The response:
{
"codes": ["482913"],
"links": ["https://example.com/verify?t=a1b2c3"]
}
A message that contains neither answers 200 with two empty arrays. It is not
a 404 — the message exists, and "no code in this mail" is an answer your test
may want to assert on.
The rules, exactly
Codes are runs of 4 to 8 digits in the text body — or in the HTML body
stripped of its tags, when there is no text body — that appear within 40
characters of one of the words code, OTP, PIN, verification, verify
or passcode, matched without regard to case. They are returned in order of
appearance, with repeats removed.
Links are every http:// or https:// URL in the text body and the HTML
body, in order of appearance, with repeats removed. Nothing is followed, and
nothing is unwrapped: a link that a mail provider has rewritten through a
click tracker is returned as it appears in the message.
These are heuristics, and that is the contract
The rules above are deliberately simple, and they are the whole of what the
endpoint promises. It does not understand your email template. A message that
puts a five-digit order number next to the word "code" will yield the order
number; a message that writes the code as 48-2913 will yield nothing.
Two consequences worth designing around:
- Assert on the shape you expect. If your test needs exactly one code,
check that
codeshas one element rather than takingcodes[0]. - Fall back to the message body.
GET /subscriptions/{sid}/messages/{id}returns thetextandhtmlin full. When extraction does not fit your template, match on the body yourself — the endpoint is a convenience, not a dependency.
Refining the rules for a template that nearly works is the kind of change that the stability policy allows at any time, so do not build a test that depends on a code not being extracted.
The request and response shapes, including every error status, are in the HTTP API contract and the API reference.