Skip to content

Email templates

Apilane supports sending emails to users for account-related events such as registration confirmation and password recovery. Each application can be configured with its own SMTP settings and customizable email templates.


SMTP configuration

Before emails can be sent, you must configure the SMTP settings for your application. Open the Email tab of your application in the Portal. Save settings saves the SMTP settings and the confirmation landing page together.

Only a person may change these settings. Portal agents with email-settings Read can inspect the configuration without its password, but no grant permits changing the SMTP transport, sender, credentials or confirmation redirect. Older email-write grants are retired while unrelated grants are retained.

Setting Description
Mail server SMTP server hostname (e.g., smtp.gmail.com)
Port SMTP port of a server that accepts STARTTLS, typically 587. Port 465 (implicit SSL) is not supported
Sender address The "From" email address shown to recipients
Sender display name The display name shown alongside the sender address
User name SMTP authentication username
Password SMTP authentication password. Once saved it is never shown again; an empty box keeps the stored value

Apilane

Required for email features

All SMTP fields must be configured for email functionality to work. If one is missing, the Email/RequestConfirmation and Email/ForgotPassword endpoints fail with an error, and so does Account/Register when the Email confirmation template is enabled. In that case the user has already been created by then, so register only after the SMTP settings are complete.

Mail is always sent over TLS. A send that fails is written to the API server's log and is not reported to the caller, so test with a real address. The log holds the recipient, the subject and the outcome of a send, never the content of the mail: a confirmation or a reset mail carries a live link, and anyone who reads the log could use it. A link in a subject is replaced by [link] there.


Available templates

Apilane provides two built-in email templates. Both are switched off in a new application: turn on Enabled in the editor of a template once the SMTP settings are filled in. A template that is off is never sent. Without the confirmation email, a user can sign in only while Allow users with an unconfirmed email to sign in is on (Security tab). Both the subject and body can be fully customized; the body is HTML (Body (HTML) in the editor). The templates are listed under Email templates on the same tab; editing one shows a live preview of its body. The Help button in the header of the tab explains the settings and the templates.

Email confirmation

Sent to the user after registration. Typically contains a welcome message and a link to confirm the user's email address.

  • Event code: UserRegisterConfirmation
  • Default subject: Welcome!
  • Default body: Thank you for creating an account.<br/>Please click on this <a href="{confirmation_url}">link</a> to confirm your email address
  • Placeholders: {confirmation_url}, {confirmation_token}

Reset password

Sent to the user when they request a password reset via the ForgotPassword API endpoint or the ready-made page (see Password reset flow).

  • Event code: UserForgotPassword
  • Default subject: Reset Password
  • Default body: Please click on this <a href="{reset_password_url}">link</a> to reset your password
  • Placeholders: {reset_password_url}, {reset_password_token}

Apilane


Template placeholders

Customize your email templates using placeholders. Apilane replaces these with actual values when sending the email.

User placeholders

These placeholders are available in all email templates:

Placeholder Description
{Users.ID} The user's ID
{Users.Username} The user's username
{Users.Email} The user's email address

The values come from the users themselves. In the body they are HTML-encoded, so a username cannot add a link or markup to the mail; in the subject they are inserted as they are.

Event-specific placeholders

Each email event has its own special placeholder:

Event Placeholder Description
Email confirmation {confirmation_url} The URL the user must follow to confirm their email address
Email confirmation {confirmation_token} The confirmation token alone (URL-safe), to build your own link
Reset password {reset_password_url} The URL the user must follow to reset their password
Reset password {reset_password_token} The password reset token alone (URL-safe), to build your own link

The URL and the token placeholder of an event expand from one token: a template that uses both hands out a single valid token. The tokens are generated as before and live as long as before (1 hour for the confirmation, 24 hours for the reset). The Portal lists the placeholders of a template under its editor.

Complete a flow on your own server

The link in the email leads to a page of the API server. To handle the flow in your own application instead, put the token in a link of yours and spend it with an endpoint:

<a href="https://app.example.com/reset?token={reset_password_token}">Reset your password</a>
Flow Placeholder Endpoint SDK
Confirm the email {confirmation_token} POST /api/Email/ConfirmEmail with { "Token" } EmailConfirmEmailAsync / emailConfirmEmail
Reset the password {reset_password_token} POST /api/Email/ResetPassword with { "Token", "Password" } EmailResetPasswordAsync / emailResetPassword

Both answer "OK" or the usual error ({ "Code", "Message", "Property" }): an unknown or expired token is VALIDATION for Token, and a new password of fewer than 8 or more than 100 characters is VALIDATION for Password, with the words of the ready-made page. Both are anonymous, need the application token, and allow 60 calls per minute per application. See the REST API reference.

A token in your own link

The token is a one-time secret. Put it in the address of a page of yours only to read it there and send it straight to the endpoint; do not log it, and keep it out of the Referer of other sites. The API server never logs it: the subject of a mail is logged with a token replaced by [token].

Example template

Hello {Users.Username},

Thank you for joining our platform!

Please click on this <a href="{confirmation_url}">link</a> to confirm 
your email address.

Best regards,
The Team

Confirmation flow

When a user registers and email confirmation is enabled:

sequenceDiagram
    participant Client
    participant API as Apilane API
    participant DB as Database
    participant SMTP as Mail Server
    participant User as User Inbox

    Client->>API: POST /api/Account/Register
    API->>DB: Create user record
    API->>DB: Generate confirmation token
    API->>API: Build confirmation URL<br/>{ServerUrl}/api/Account/Confirm?appToken=...&token=...
    API->>API: Replace {confirmation_url} in template
    API->>SMTP: Send confirmation email
    SMTP->>User: Deliver email
    API-->>Client: Registration success
    Note over User: User opens email
    User->>API: GET /api/Account/Confirm?appToken=...&token=...
    API->>DB: Mark email as confirmed
    API-->>User: Redirect to Email confirmation redirect URL
  1. User registers via POST /api/Account/Register
  2. Apilane generates a unique confirmation token
  3. The confirmation URL is built as: {ServerUrl}/api/Account/Confirm?appToken={appToken}&token={confirmationToken}
  4. The {confirmation_url} placeholder is replaced with this URL in the email template
  5. The email is sent to the user
  6. When the user clicks the link within 1 hour, their email is marked as confirmed
  7. The browser redirects to the Email confirmation redirect URL (configurable in Application settings). A link that is older than an hour, or unknown, leads to an error page of the API server instead; the user then asks for a new email via Email/RequestConfirmation

{ServerUrl} is the address of the API server as it is registered in the Portal, written in lower case.

Re-sending confirmation

If a user loses their initial confirmation email, they can request a new one via the Email/RequestConfirmation API endpoint.


Password reset flow

When a user requests a password reset:

sequenceDiagram
    participant Client
    participant API as Apilane API
    participant DB as Database
    participant SMTP as Mail Server
    participant User as User Inbox

    Client->>API: GET /api/Email/ForgotPassword?email={email}
    API->>DB: Look up user by email
    API->>DB: Generate reset token
    API->>API: Build reset URL<br/>{ServerUrl}/App/{appToken}/Account/Manage/ResetPassword?Token=...
    API->>API: Replace {reset_password_url} in template
    API->>SMTP: Send password reset email
    SMTP->>User: Deliver email
    API-->>Client: OK (always, even if email not found)
    Note over User: User opens email
    User->>API: Follow reset link
    API-->>User: Show password reset form
    User->>API: Submit email and new password
    API->>DB: Update password
    API-->>User: Password changed confirmation
  1. Client calls GET /api/Email/ForgotPassword?email={email}
  2. Apilane generates a unique reset token
  3. The reset URL is built as: {ServerUrl}/App/{appToken}/Account/Manage/ResetPassword?Token={resetToken}
  4. The {reset_password_url} placeholder is replaced in the email template
  5. The email is sent to the user
  6. The user follows the link and fills in a form with their email address, the new password (8 to 100 characters) and its confirmation. The password is changed only when the address is the one the link was sent to

There are two ways to start a reset: call the endpoint from your own screen, or send the user to the ready-made page {ServerUrl}/App/{appToken}/Account/Manage/ForgotPassword (shown on the Security tab, card Forgot password), where they type their address. Both send the Reset password email, and both ask for the same limit (see the note below).

The link works for 24 hours. A successful reset invalidates all outstanding reset links and all of the user's existing sessions, including cached bearer and signed-request credentials. The user must sign in again with the new password.

Security note

Both RequestConfirmation and ForgotPassword endpoints return success even if the email does not exist in the system. This prevents email enumeration attacks. They fail with an error when the application has no complete SMTP settings or the address is not a valid email address (at most 254 characters), and each allows one call per 5 minutes for the same address (RATE_LIMIT_EXCEEDED). They also share an aggregate limit of 60 calls per minute per application, including unknown addresses. The ready-made forgot-password page uses the same allowances as ForgotPassword. A page that is over the limit answers 429 and shows the form again with 'Too many requests'. Rate-limit state expires and is bounded; when its capacity is reached, new requests are refused instead of dropping live limits. With incomplete SMTP settings the page shows its error page for every address without using the allowance. Whether the mail was delivered is not reported.

Tokens in the logs

The links in the emails carry their one-time token in the query string (token= in the confirmation link, Token= in the reset link). The API server does not write it to its log: the log of a send holds no content, and the log of a request shows the value of a parameter whose name contains token, password, secret or signature as ***. A reverse proxy in front of the API writes the whole address into its own access log, and the browser keeps it in its history, so restrict access to those logs. Keep the log level of Microsoft.AspNetCore.Hosting.Diagnostics at Warning, as in the committed appsettings.json: at a lower level ASP.NET itself writes every request with its query string.


Confirmation landing page

After a user confirms their email by following the URL provided in the email, the browser eventually lands on a page. By default this is a page of the Portal ({PortalUrl}/account/email-confirmed, where PortalUrl is the API's setting). To use a URL of your choice, set Redirect URL under 'Email confirmation landing page' on the Email tab.

Apilane