Skip to content
SendByte
Start sending

Changelog

Every release, in the open: what is new, what got better and what we fixed. Page 2 of 4.

  1. New

    Export your send history as CSV

    There is now an Export CSV button in the toolbar above your email log, and a matching GET /v1/emails/export if you would rather script it. It downloads your send history as a spreadsheet: when each message went out, its status, who it went to, the subject, which domain it was sent from, opens and clicks, and the message id so you can look any row back up through the API.

    The important part is that the file matches what you are looking at. Whatever filters are on when you press the button travel with the download, so a search for one recipient with the status set to bounced gives you a file of exactly that, not your whole history under a misleading filename. The per-domain log exports just that domain.

    Two things worth knowing before you open the file.

    It covers the same window your plan lets you read. The email log has always shown a bounded stretch of history, from a week on Free up to ninety days on Scale, and the export honours the same boundary rather than pretending to be a complete archive. The file carries headers naming the exact window it covers, and the log page tells you what your plan keeps. Older sends are hidden, not deleted, and they come back in both places on a plan with a longer window.

    Subjects that begin with an equals sign are prefixed with an apostrophe. Your recipients did not choose their subject lines, but a reply, a forwarded thread or an imported name can put text you did not write into a cell, and a spreadsheet will happily execute a cell starting with = the moment the file is opened. Making it text is the difference between a spreadsheet and a way in.

  2. Fixed

    A degraded domain stops sending you on a wild goose chase

    There is a gap between your DNS recovering and us being able to act on it. If your DKIM record disappears for a few hours we mark the domain Degraded, and once the record comes back we have to wait for Amazon to re-read it and re-confirm the key before sending can resume. That re-confirmation takes up to an hour, sometimes a little more. It is not something a button can hurry.

    The banner on your Domains page did not say any of that. It said “A required record changed. Check again, then re-add anything missing below” and named no record, while every record in the table underneath it read Found. That is a contradiction with no way out of it, and the only thing it invites you to do is click Check verification over and over, which cannot help. One customer clicked it about twenty times in an hour before writing in, and their DNS had been correct the whole time.

    The banner now reads the same DNS results you are looking at. If a required record genuinely fails the check, it names that record and asks you to re-add it, as before. If every record resolves, it says the records were found, that re-verification finishes on its own, usually within the hour, and that there is nothing to re-add and no reason to check again. Same wait, but you now know what you are waiting for and that you are not the one holding it up.

  3. Fixed

    A rejected address is no longer your bounce

    Some addresses never make it out of our building. If you send to something like someone@gmail.com. with a stray dot on the end, our mail provider refuses to accept the message at all, and no mailbox provider anywhere ever sees it. Until today we recorded that refusal as a bounce against your account, exactly as if Gmail had told us the mailbox did not exist.

    That mattered more than it sounds. Bounces feed the safety check that pauses sending when a project’s bounce rate climbs high enough to endanger its own delivery, and a single malformed address could be the one that tipped a project over the line. One customer was paused for three days on a rate that only crossed the limit because a rejection of ours had been counted as theirs.

    Both halves are fixed. A message our provider refuses at submission no longer counts as a bounce, and no longer counts as a send either, because it was never sent. And a malformed address is now caught the moment you call the API: you get a 422 naming the problem, before the message is accepted or billed, instead of finding it later as a bounce in your log. If a signup form is letting typos through, you will now hear about it at the point of the mistake.

    Real bounces are unchanged. A mailbox that does not exist, a full inbox, a server that rejects you: those are still yours, still counted, and still the thing to watch.

  4. Fixed

    A DNS blip no longer flags your domain

    The hourly domain check we added last week was too quick to accuse you. It read a DKIM record once, and if that single lookup came back empty it marked the domain Degraded and emailed you to go and fix your DNS. Worse, it could not tell the difference between two very different answers: “this record is not published” and “your nameserver did not reply to me”. A momentary resolver failure on our side therefore read as a broken record on yours, and at least one customer spent an afternoon re-checking records that were correct all along.

    Both halves of that are now fixed. A lookup that never gets an answer is discarded rather than counted, because that tells us something about our network and nothing about your DNS. A lookup that does answer, and answers that the record is absent, has to say so three checks in a row before the domain is flagged. Any single reading where the record is present resets the count. In practice you will only see Degraded now if the record has genuinely been missing for a few hours, which is what it was always meant to mean.

    Two webhook improvements landed alongside it. When we stop calling an endpoint that has been failing for a long time, the deliveries that were still queued for it are now closed off as failed instead of sitting at Pending forever, so the delivery list stops implying we are still trying when we are not. And when your endpoint rejects a delivery, we now keep the start of its response and show it in a Last response column next to the attempt count. If your endpoint answers with a reason, you can now read that reason yourself instead of seeing only a status code.

  5. Fixed

    Gmail "Send mail as" works over our SMTP relay

    If you connected Gmail to smtp.sendbyte.africa using Gmail’s “Send mail as” feature, every message you sent was rejected with a 550 error complaining about line breaks in a header. This was our bug, it was not something you had misconfigured, and it affected every Gmail user of the relay rather than a handful of unlucky ones.

    The cause. Long email headers are legally split across several lines, which the standard calls folding. Gmail attaches a header called X-Gm-Message-State to everything it sends, and that value is always long enough to be folded. We were reading those header lines exactly as they arrived, folds and all, and then handing them to a safety check that refuses line breaks in a header value. That check exists for a good reason: it stops an attacker smuggling extra headers, such as a hidden Bcc, into a message. It just could not tell the difference between an attack and a header that had been split the way the standard says it should be.

    Now we unfold those headers back into a single line before checking them, which is simply reading the header correctly. The safety check is unchanged and still refuses a line break that is not a legitimate fold, and in that case we drop the one suspicious header rather than the whole message. The same fix covers every custom header a provider adds, not only Gmail’s, so other clients that fold long headers will work too.

    If you had given up on Gmail “Send mail as” with SendByte, it is worth trying again. Nothing needs changing at your end.

  6. Fixed

    We now watch your domain after it verifies

    Verifying a sending domain was treated as a one-time event. Once it passed, we never looked at it again. If the DKIM record was later removed or changed at your DNS provider, which happens when a domain moves hosts or records get tidied up, sending would stop working while your dashboard still showed the domain as verified. There was no warning, and the failures looked like ordinary bounces.

    Every verified domain is now re-checked every hour. If the record is still published but the underlying platform had stopped trusting it, we repair that ourselves and you never notice. If the record is genuinely gone, the domain is marked Degraded, you get an email naming the exact record to republish, and the API returns an error that says so instead of accepting mail that cannot be delivered. Put the record back and the domain returns to verified on its own, with nothing to click.

    We also fixed a related problem underneath it. When sending was refused because of this, we recorded it as a hard bounce against the recipient and added them to the suppression list, even though the recipient had done nothing wrong and the message never reached them. That no longer happens, and the addresses affected by it have been cleared.

  7. Fixed

    Removing a suppression now sticks

    Removing an address from your suppression list cleared it on our side but left it blocked one level deeper, in the sending platform underneath us. The next message to that address was refused there, came back as a bounce, and put the address straight back on your list. If you removed an address and found it blocked again moments later, this was why.

    Removal now clears the block in both places, so it holds. A refusal that comes from our own list is also no longer counted as a bounce against you, which means it can no longer affect your bounce rate or pause your sending.

    If you have been fighting with an address that would not stay removed, request removal once more and it will stay off.

  8. Improved

    We email you when sending is paused

    If your bounce or complaint rate crosses a safe threshold, we pause sending on the project to protect your domain and everyone else on the platform. Until now that pause was silent, so the first sign of it was your sends being rejected.

    You now get an email the moment it happens. It names the rate we measured, the limit, how many sends the measurement covers, and up to twelve of the recipients that actually failed, with the reason each receiving server gave. That is enough to clean the list and ask us to lift the pause, instead of guessing what went wrong.

  9. Fixed

    Suppressions tell you when an address is blocked again

    When you removed an address from your suppression list and the recipient confirmed it, the removal went through. If that address then failed again, we put it back on the list to protect your sending reputation, but the Suppressions page kept showing it as Removed. Sends to it were rejected and nothing told you why.

    That state now reads Blocked again, and we email you as soon as it happens, quoting the reason the receiving mail server gave. If your webhooks are scoped to specific events, you can subscribe to the new suppression.removal.reverted event.

    A repeated block almost always means the mailbox itself is still refusing mail. The most common cause is a domain listing more than one mail provider where the address only exists on one of them, so check that the address works on every provider your domain points at before requesting removal again.

  10. Fixed

    Deleted brands no longer use up your subscriber allowance

    Every plan includes a number of subscribers. If you deleted a brand, the subscribers stored under it were still counted against that number, even though a deleted brand disappears from your dashboard the moment you delete it.

    The effect was hard to make sense of from the outside. Your dashboard would show few subscribers, or none at all, while any attempt to import more was rejected with a message saying you were over your plan’s subscriber limit. There was no screen anywhere that would show you the subscribers causing it, because they belonged to a brand you had already deleted.

    Your subscriber count now includes only the brands you can actually see and use. Deleting a brand frees its share of your allowance immediately, and the number shown in your dashboard is the same number we enforce.

    If you hit this, you do not need to do anything: your allowance was corrected automatically and you can import again. Deleted brands are still recoverable, so if you removed one by mistake, contact support and we can bring it back with its lists intact.

  11. Fixed

    Fixed: searching the email log only looked at your most recent sends

    The search box on the email log was not searching your email log. It was searching only the page of sends the screen had already loaded, which was the most recent hundred. If you send a few hundred emails a day, that is roughly the last hour, so a recipient from yesterday morning simply never appeared and the log looked as though it had lost your mail.

    Nothing was ever lost. Every one of those sends was still there, inside your plan’s history window, and still visible through the API. The log page just could not reach past its first page, and there was no way to page any further back either.

    Searching now runs against your full history rather than one screenful, and the log is properly paginated, so you can walk back through everything your plan keeps. The status filter and the date range already worked this way; search and paging now match them. Searching a recipient address or a subject line returns every match in the window, with a count of how many there are.

    We also made it fast rather than merely correct. Looking up one recipient used to mean reading every message in your account, which took about half a second on our largest project and would have kept getting slower as accounts grow. It is now indexed and returns in well under a millisecond.

    Thank you to the customer who reported this, and who worked out our page size from the outside while doing so.

  12. Fixed

    Annual plans now get their included emails every month

    Your plan’s included emails are a monthly allowance, whatever billing cadence you are on. On an annual plan, the counter that enforces that allowance was not resetting each month. It reset once a year, on your renewal date.

    Your usage page always showed the correct monthly figure, so the problem was invisible until the counter behind it filled up. Once it did, further sends would have been treated as extra usage and billed as overage, even though they sat inside the allowance you had already paid for.

    The counter now rolls forward one month at a time on every plan, so an annual subscription behaves as twelve monthly ones for allowance purposes. Nothing changes for monthly plans, and no account was overbilled: we found this while auditing usage and fixed it before any annual account crossed the line.

    One related change: if your plan changes twice inside the same calendar month, the second change no longer restarts your allowance from zero. It carries over what you have already sent that month.

  13. Fixed

    Fixed: email addressed to a company could be mistaken for impersonating it

    If your product emails a company about that company, our abuse filter could read it as an attempt to impersonate them and refuse the send with a content_flagged error. A job application naming the employer, a sales enquiry naming the prospect, an invoice naming the client, a sign-in link sent to your own second domain: all of them were caught this way. In the worst cases the account was suspended automatically rather than the single message being rejected.

    The filter is there for a real attack, where someone emails a company’s staff while posing as that company. The mistake was treating any mention of the recipient’s name as that claim. Naming a company in your subject line is simply what mail addressed to that company looks like. And a business that runs more than one domain was only ever compared against the one it happened to send from, so its own second domain looked like a stranger’s.

    Three things have changed. Only the sender name can establish a claim of identity now, so naming a company in a subject line no longer counts against you by itself. Every domain on your project is recognised as yours, not only the one a given message was sent from. And a word that two companies merely happen to share is no longer read as an identity.

    Suspending an account also takes more than one signal now. A questionable message is still refused, but switching off an account waits for a second signal to agree, because a wrong refusal costs you one email while a wrong suspension costs you your whole service.

    Before releasing this we replayed it over every message sent through SendByte in the last thirty days, to confirm it gives up no protection that real traffic depends on. If you were blocked or suspended by this, your account has already been put right and you will have heard from us directly.

  14. New

    Upload images straight into a campaign

    Adding a picture to a campaign used to mean finding somewhere to host it first, then coming back and pasting the web address. You can now upload the image where you need it. Click to choose a file or drop one onto the image block, and it goes straight into the email.

    The address field is still there and still editable, so if you already host your images somewhere you can carry on pasting links exactly as before.

    Two things worth knowing. SVG files are turned away on purpose: Gmail and Outlook do not display them in email, so the picture would simply be missing for most of the people you send to. Export as PNG instead. And if you upload something far larger than an email needs, we will say so, because a heavy image makes your message slower to open without looking any better.

    Uploads are limited to 5 MB, and PNG, JPG and GIF all work.

  15. Fixed

    Fixed: a blank campaign would not take any content

    Starting a campaign from scratch left you with an editor that would not accept anything. Clicking “Add to the end” opened the list of parts, and choosing Heading, Text, Button or any of the others simply closed the list again. Nothing appeared, and no error explained why. Starting from one of the templates worked normally, so the problem only showed up if you wanted to write your own email from an empty page.

    A campaign holds its design as a document, and each part you add is placed inside that document. A campaign begun from scratch has no document yet, and the editor had nowhere to put the first part, so it quietly did nothing rather than saying so.

    The first part you add now creates the document it needs, and everything after it lands where you would expect. If you tried to build a campaign this way and gave up, it will work now. Campaigns you had already started from a template were never affected, and no saved work was lost.

  16. Improved

    Marketing is included in the plan you already have

    Now that campaigns are live, the pricing page spells out what that means for your bill: nothing changes. Marketing email is included on every plan, including Free. Campaigns, lists, segments, signup forms and automation are all there, with no add-on and no second subscription.

    What your plan sets is how much audience you can hold. Free covers 1 brand and 500 subscribers, Startup 2 brands and 2,000, Starter 3 and 10,000, Growth 10 and 50,000, and Scale has no limit on either. Those numbers have always been in place; they are now published on the pricing page and shown on the plan cards in your dashboard, so you can see the ceiling before you reach it.

    Campaign sends draw from the same monthly email quota as your transactional mail. One email to one subscriber is one email, exactly as it is on the API, so a 5,000-recipient campaign uses 5,000 of your quota and bills at your normal overage rate beyond it. One quota, one bill, both channels.

  17. Fixed

    Fixed: a page of raw code instead of the dashboard

    Occasionally, moving between dashboard pages would land you on a screen of unreadable code with a URL ending in index.txt. Going back and clicking again always worked, which made it easy to dismiss and hard to pin down.

    The cause was a dropped request. When the dashboard loads a page, it fetches that page’s data separately from the page itself. If that one request failed, from a brief loss of signal, a sleeping tab waking up, or a deploy landing mid-click, the dashboard fell back to a full page load but pointed the browser at the data file rather than the page. Your browser did what it was told and showed you the file.

    The fallback now sends you to the page, so a dropped request costs you a reload instead of a wall of code. Nothing was ever wrong with your account or your data.

  18. New

    Send marketing campaigns to your own lists

    You can now send newsletters and campaigns from SendByte, alongside the transactional email you already send. Look for Marketing in the dashboard.

    Everything lives inside a brand: your lists, your subscribers, your templates, your campaigns and your reports. If you run more than one product or client, each gets its own brand with its own sending domain and its own audience, kept completely separate.

    Lists come with the parts you would expect: single or double opt-in, custom fields, segments built from dropdowns rather than typed conditions, a hosted subscribe form, and autoresponders that go out when someone joins or on a date you choose. Housekeeping shows you what it will remove before it removes it.

    Campaigns start from a template rather than a blank page. Pick one from the store, then edit the actual parts of it, the headline, the words, the picture, where the button points, with the real email rendered beside you as you type. If you would rather write the markup yourself, MJML and plain HTML both work.

    Your campaigns will not damage your transactional sending. Marketing leaves through a completely separate sending reputation from your receipts, password resets and alerts. A newsletter that collects complaints cannot drag down the mail your product depends on. That separation is infrastructure, not a policy we promise to enforce.

    Every campaign carries an unsubscribe link whether you add one or not, and unsubscribes, bounces and complaints are processed for you and reflected on your lists automatically.

    Coming from Sendy? The suite is built around the same shape, so most of what you know transfers. Paste a Sendy template and we will spot its tags and offer to convert them in one click. There is a migration guide in the docs covering what maps to what and the handful of things that behave differently.

    To send marketing from a domain, add two extra DNS records shown in your brand settings. Your campaigns will go out without them, but adding them puts your own domain in the “mailed by” line inboxes show, instead of ours.

  19. Fixed

    Upgrades covered in full by a discount now confirm properly

    If your account carries a discount that covers a plan’s whole monthly fee, there is nothing to pay, so we activate the plan for you rather than sending you to a payment page. The upgrade screen did not handle that case. It tried to send you to a checkout that was never created, and you landed on an error page even though your plan had in fact been activated.

    The upgrade screen now recognises this and confirms it clearly: it tells you the plan is active, that your discount covered it in full, and that no card was charged.

    If you hit this before, your upgrade did go through and you were not charged. Your plan has been active the whole time. You can check it on the Billing page.

  20. Improved

    Attachments in the email log

    The email log now shows the files that went out with a message. Open any email and you will see each attachment with its type and size, plus a download link, so you can check exactly what a recipient received without digging through your own code.

    Inline images render properly in the preview too. Until now the log displayed the raw message body, so an image embedded with a cid: reference showed as broken even though the delivered email was correct. Inline images are labelled and show their Content-ID, which is the thing to compare against your HTML when a preview does not look the way you expect.

    Download links are signed and short-lived, so they expire a few minutes after you open the email. Reopening it gives you a fresh link. Attachments are stored for 30 days, so a download link is only available for mail sent inside that window.