Skip to content

Quick start

This sends your first test message through Flyanote's API with curl. A test send is free and never delivered: it shows your integration works. Then it adds your domain, which takes a live key. Steps 1 to 3 are sandbox steps; step 4 is live.

Before you start

  • An account. Today a person opens it in a browser, with an invite: accounts are by invite while Flyanote is in development, and sign-up opens early 2027. To ask for one, email hello@flyanote.com.
  • A test key. In the app, open API keys and make a key in Test mode that can “Send email” and “Check what happened to messages”. It's shown once, so copy it.
  • curl, in a terminal.

Put the key in a variable, with your key in place of fan_test_…:

export FLYANOTE_API_KEY='fan_test_…'

1. Check the key (sandbox)

curl -sS https://app.flyanote.com/api/v1/api-keys/current \
  -H "Authorization: Bearer $FLYANOTE_API_KEY"

The answer is the key itself, never its secret: its mode is test, and scopes lists messages:send and messages:read.

2. Send a test message (sandbox, free)

Put the address you signed up with in place of you@example.com: until the account has a verified domain and credit, it sends only to its own members’ verified addresses.

curl -sS https://app.flyanote.com/api/v1/messages \
  -H "Authorization: Bearer $FLYANOTE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: quickstart-1" \
  -d '{
    "from": {"address": "test@sandbox.flyanote.com", "name": "Quick start"},
    "to": "you@example.com",
    "subject": "My first test send",
    "text": "Sent through the Flyanote API."
  }'
  • test@sandbox.flyanote.com is the sandbox sender: any test key may send from it before the account has a domain.
  • Idempotency-Key is required: a value unique to this message. If the request fails or times out, send it again with the same key and the same body, and it won't send twice.
  • To send another message, change the key, to quickstart-2 say. The same key with a different body is refused with 409, and the same key and body within 24 hours return the first answer without sending again.

The API answers 202 Accepted: accepted isn't delivered, and a test message never is. curl prints the answer's body, like this one with the message's own id:

{"id": "msg_…", "status": "queued", "template": null, "warnings": []}

3. See what happened (sandbox)

The key needs “Check what happened to messages”. Put the id from step 2 in place of msg_…:

export MESSAGE_ID='msg_…'
curl -sS "https://app.flyanote.com/api/v1/messages/$MESSAGE_ID" \
  -H "Authorization: Bearer $FLYANOTE_API_KEY"

Within a few seconds its status is test, where a test message ends. If it's failed, reason.code says why and reason.retryable whether sending it again may work: tier0_recipient_not_member means to wasn't a member's verified address.

4. Add your domain (live)

Adding a domain sets it up for real sending, so it takes a live key: test keys can't. Make one that can “Add and remove domains” and “See your domains”, then put it in a variable:

export FLYANOTE_LIVE_KEY='fan_live_…'

Use your organization's own domain, not a free mailbox provider's, in place of example.com:

curl -sS https://app.flyanote.com/api/v1/domains \
  -H "Authorization: Bearer $FLYANOTE_LIVE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com"}'

The answer's records are the DNS records to add at your DNS host: a CNAME for DKIM and one for MAIL FROM, and a DMARC record it suggests when the domain has none. Each gives its name in full and its host as most DNS hosts want it. Adding the same domain again returns it, so a retry is safe.

Flyanote checks for the records on its own for 3 days. To check now, put the domain's id in place of dom_…:

export DOMAIN_ID='dom_…'
curl -sS -X POST "https://app.flyanote.com/api/v1/domains/$DOMAIN_ID/check" \
  -H "Authorization: Bearer $FLYANOTE_LIVE_KEY"

Then read the domain:

curl -sS "https://app.flyanote.com/api/v1/domains/$DOMAIN_ID" \
  -H "Authorization: Bearer $FLYANOTE_LIVE_KEY"

Once verification.state is verified, the domain can send. Until then, each record's problem says what's wrong with it in DNS: missing, wrong_value, duplicate, or, for DMARC, invalid.

Two states end the checking. stopped means 3 days passed without the records: checking again starts 3 more days. setup_failed means Flyanote couldn't set the domain up, and setup.failure says why (domain_in_use, say): checking again does nothing, so remove the domain and add it again once the cause is fixed.

Sending live

A live send is the request in step 2 with your live key, from an address on your verified domain. It needs credit: while Flyanote is in development, we add credit on request. Live mail opens to customers with the private beta, and this page adds that step then.

Next