Here's a thing that surprises people the first time: an email sent through the API does not carry the signature the user set up in Gmail or Outlook. Provider signatures live in the provider's compose UI, and a programmatic send bypasses that entirely, so a message your app sends goes out with no signature at all unless you add one. The Nylas Signatures API is how you add it: store an HTML signature once, then attach it to a send by ID, and the signature gets appended to the message for you.
This post covers signatures from two angles: the HTTP API your backend calls, and the request, and Nylas appends the signature's HTML to the end of the message body at send time. You don't concatenate anything yourself; you write the body, name the signature, and the recipient sees the body followed by the sign-off.
curl --request POST \
--url "https://api.us.nylas.com/v3/grants/<GRANT_ID>/messages/send" \
--header "Authorization: Bearer <NYLAS_API_KEY>" \
--header "Content-Type: application/json" \
--data '{
"to": [{ "email": "[email protected]" }],
"subject": "Quarterly update",
"body": "<p>Hi, here is the quarterly update...</p>",
"signature_id": "<SIGNATURE_ID>"
}'
One detail worth knowing for replies: the signature is appended after any quoted text in a reply or forward, so it lands at the end of the message, below your new text and the quoted thread, rather than at the very top. The same signature_id works on the Drafts API too: pass it when you create a draft with POST /v3/grants/{grant_id}/drafts, or when you send an existing draft, and it's appended the same way. From the CLI, it's the --signature-id flag on nylas email send and nylas email drafts create, so a signature can ride along on a draft that's reviewed before sending.
There's no server-side notion of a default signature, so your application decides which signature_id to attach on each send. The clean pattern is to store the user's preferred signature ID alongside their grant in your own database and read it at send time, falling back to none when a particular message shouldn't carry one. That keeps the choice in your control rather than implicit, which matters once a user has more than one variant.
Keep variants for different contexts
People don't sign every email the same way, and a grant supports up to 10 signatures so you can keep variants. A common set is "Work" for client mail, "Personal" for everything else, and "Mobile" for a shorter sign-off, each stored separately and chosen per send by its ID. Your application picks which signature_id to attach based on whatever context it's sending in.
That cap of 10 per grant is generous for personal variants but worth keeping in mind if you're tempted to generate a signature per campaign or per template, which would burn through it fast. Signatures are for a user's sign-off, not per-message branding; for message-level variation, the content belongs in the body or a template, and the signature stays the stable identity at the bottom. Treat the 10 slots as a small set of a person's real sign-offs.
Provision signatures per user on connect
In a multi-user app, you create a signature per grant as part of onboarding. When a user connects their mailbox and you get a grant ID, that's the moment to create their signature, either from a default template you fill with their name and title or from input they provide in your UI. From then on, every send from that grant attaches their signature_id.
This scales cleanly because signatures are grant-scoped: each user's sign-off is isolated to their own connected account, and you never cross-contaminate one user's signature onto another's mail. For a product where every user sends from their own mailbox, provisioning the signature at connect time and storing its ID alongside the grant in your database is the pattern, so the right sign-off is always one field away at send time.
Preview a signature before you rely on it
Before wiring a signature into production sends, confirm it renders the way you expect. There's no separate render endpoint for signatures the way there is for templates, so you preview one of two ways. Fetch the signature with a GET and drop its HTML body into a preview pane in your own interface, or send a test message to yourself with the signature_id attached and look at the real result. The second is the more honest check, since it runs the signature through the actual append-and-send path that a real message takes.
Manage your signatures
Signatures support the full CRUD set on /v3/grants/{grant_id}/signatures. A GET lists every signature on the grant, GET /v3/grants/{grant_id}/signatures/{signature_id} fetches one, PUT updates a signature's name or body, and DELETE removes it. The CLI mirrors these with nylas email signatures list, show, update, and delete.
nylas email signatures list
nylas email signatures show <signature-id>
Each signature in the list comes back with its name and ID, so your interface can present them as a picker and let a user choose which sign-off a message uses. Because the list is grant-scoped, a query only ever returns the signatures for the account you asked about, which keeps a multi-user app from leaking one person's variants into another's picker.
Updating is how a sign-off change propagates: edit the signature once, and every future send that references its ID picks up the new HTML, the same decoupling that makes any stored resource worth using over an inline string. When a job title changes or the company rebrands, you update the body in one place rather than hunting through send sites.
Lifecycle: signatures follow the grant
Because signatures are grant-scoped, their lifecycle is tied to the grant. They're created against a specific connected account, they're only usable on sends from that grant, and they're automatically deleted when the parent grant is deleted. You don't have to clean them up separately when a user disconnects; removing the grant takes its signatures with it.
This is the right behavior, since a signature is meaningless without the mailbox it signs for. It also means that if a user re-authenticates by deleting and recreating a grant rather than refreshing it, the signatures don't carry over, and you'd recreate them against the new grant. It's one more reason to re-authenticate an expired grant in place rather than tearing it down, so the stored signatures survive.
Things to keep in mind
A short list of practices keeps signatures predictable.
Provider signatures don't apply. Mail sent through the API never inherits the user's Gmail or Outlook signature; attach a stored one explicitly or there's none.
Attach bysignature_idon the send. A stored signature is inert until a send references it; Nylas appends the HTML for you.
It lands after quoted text. On replies and forwards, the signature goes at the end of the message, below the quoted thread.
Ten per grant. Keep them to a user's real sign-off variants; don't spend the cap on per-message branding.
They die with the grant. Signatures are deleted when the grant is, so re-authenticate in place to keep them.
Write email-safe HTML. Inline styles, hosted image URLs, and simple structure render across clients; test in Outlook before trusting it.
Wrapping up
Signatures fill the gap a programmatic send leaves: the provider's own sign-off doesn't come along, so you store an HTML signature on Nylas and attach it by ID. Create one with POST /v3/grants/{grant_id}/signatures or nylas email signatures create, pass its signature_id on a send, and it's appended to the body, after quoted text on replies, with nothing for you to concatenate. Keep a handful of variants per grant, update one to change the sign-off everywhere, and let the grant's lifecycle clean them up.
Where to go next:
and — thesignature_idfield and other send options
Send email — where the signature gets attached
SOCIAL SHARE CARD GENERATOR