Verifalia provides a fast and accurate API for verifying email addresses in real-time to determine their deliverability. This SDK library integrates seamlessly with Verifalia and allows you to verify email addresses and manage most account settings in Go v1.18 and higher.
If this SDK helps you ship features faster, we'd love your support! By starring our GitHub repository, you help us gauge how widely it's used and which features and improvements to prioritize next. Every star makes a difference — thank you for helping steer the future of this SDK!
To learn more about Verifalia, please visit https://verifalia.com.
Verifalia is an online service that provides email verification and mailing list cleaning; it helps businesses reduce their bounce rate, protect their sender reputation, and ensure their email campaigns reach the intended recipients. Verifalia can verify email addresses in real-time or in bulk, using its API or client area; it also offers various features and settings to customize the verification process according to the user's needs.
Verifalia's email verification process consists of several steps, each taking fractions of a second: it checks the formatting and syntax (RFC 1123, RFC 2821, RFC 2822, RFC 3490, RFC 3696, RFC 4291, RFC 5321, RFC 5322, and RFC 5336) of each email address, the domain and DNS records (including the MX records), the mail exchangers, and the mailbox existence, with support for internationalized domains and mailboxes. It also detects risky email types, such as catch-all, disposable, or spam traps / honeypots.
Verifalia provides detailed and accurate results for each email verification: it categorizes each email address as Deliverable,
Undeliverable, Risky, or Unknown, and assigns one of its exclusive set of over 40 status codes.
It also explains the undeliverability reason and provides comprehensive verification details. The service allows the user to choose the desired
quality level, the waiting timeout, the deduplication preferences, the data retention settings, and the callback preferences
for each verification.
To learn more about Verifalia please see https://verifalia.com
- Adding this library to your Go project
- Authentication
- Email Verifications
- How to Verify an Email Address
- How to Verify a List of Email Addresses
- How to Import and Verify a File of Email Addresses
- Processing Options
- Wait Options
- Completion Callbacks
- Retrieving Jobs
- Exporting Email Verification Results in Different Output Formats
- Don't Forget to Clean Up When You're Done
- Iterating Over Your Email Verification Jobs
- Managing Credits
- Users and Team Management
- X.509 Client Certificates
- Contact Methods
- Changelog / What's New
First, add the Verifalia Go SDK as a new module to your Go project:
# First line is optional if your project is already defined as a Go module
go mod init <YOUR_PROJECT_NAME>
go get github.com/verifalia/verifalia-go-sdk/v2To update the SDK use go get -u to retrieve the latest version of the SDK:
go get -u github.com/verifalia/verifalia-go-sdk/v2Authentication to the Verifalia API is performed using the credentials of a Verifalia user account. While you can use the same credentials you used to register your Verifalia account for API access, for security reasons, we strongly recommend creating and using a dedicated user account for API operations. This approach allows you to assign only the specific permissions needed for your application.
If you don't have a Verifalia account, you can register for a free one.
The Verifalia API supports multiple authentication methods:
- Basic authentication: Ideal for server-to-server communications
- Bearer token authentication: Useful for browser apps and client-to-server communications
- X.509 client certificate: Provides the highest level of security
The sections below describe each authentication method in detail. For more information about authenticating to the Verifalia API, see the API reference documentation at https://verifalia.com/developers#authentication.
Once you have your Verifalia credentials, provide them to the NewClient() function to create a new instance of the
Client type, which serves as the entry point for all operations against the Verifalia API. The supplied
credentials are automatically provided to the API using HTTP Basic Authentication.
package main
import (
"github.com/verifalia/verifalia-go-sdk/v2/verifalia"
)
func main() {
client := verifalia.NewClient("username", "password")
// ...
}Bearer authentication offers enhanced security over HTTP Basic Authentication. While Basic Auth requires sending actual credentials with each API call, Bearer authentication only requires credentials for an initial, dedicated authentication request. However, the initial authentication request required by Bearer authentication takes additional time. If you need to perform only a single request, HTTP Basic Authentication provides the same degree of security and is faster.
// ...
client := verifalia.NewClientWithBearerAuth("username", "password", nil)
// ...Multi-factor authentication (MFA) is supported by implementing a custom TOTPTokenProvider interface, which acquires
the time-based one-time password from an external authenticator app or device. To enable multi-factor authentication
for your Verifalia account, configure your security settings in the client area.
type myTOTPProvider struct {
auth.TOTPProvider
}
func (p myTOTPProvider) ProvideTOTP(ctx context.Context) (string, error) {
fmt.Print("Enter your TOTP token: ")
// Read the TOTP from the console
reader := bufio.NewReader(os.Stdin)
line, _ := reader.ReadString('\n')
line = strings.TrimSpace(line)
return line, nil
}
// ...
totpProvider := auth.TOTPProvider(myTOTPProvider{})
client := verifalia.NewClientWithBearerAuth("username", "password", totpProvider)
// ...This authentication method uses a cryptographic X.509 client certificate to authenticate against the Verifalia API through the TLS protocol. This method, also called mutual TLS authentication (mTLS) or two-way authentication, offers the highest degree of security because only a cryptographically-derived key (not the actual credentials) is sent over the wire with each request.
// my-cert.pem contains both the public AND private keys, in this example
cert, err := tls.LoadX509KeyPair("my-cert.pem", "my-cert.pem")
if err != nil {
panic(err)
}
client := verifalia.NewClientWithCertificateAuth(cert)
// ...All operations related to verifying and validating email addresses are performed through the EmailVerification field
exposed by the Client instance you created above. This field provides useful methods and in the following sections
we'll examine the most commonly used ones. We strongly recommend exploring the library and consulting the embedded godoc
for additional capabilities.
Important: The library automatically waits for email verification jobs to complete. If needed, you can adjust the wait options and have more control over the underlying polling process. Please refer to the Wait Options section below for additional details.
To validate an email address from your Go application invoke either the Run() method, which accepts just the email
address to test (in addition to the ubiquitous context.Context), or the RunWithOptions() method which also allows
to specify any verification options you wish to pass to Verifalia, including expected result quality and processing
priority.
Note
If you need to verify a list of email addresses, we recommend submitting them all at once using one of the dedicatedRunStrings()/RunStringsWithOptions()methods (see the following sections) rather than iterating over the source set and submitting addresses individually. The batch approach is not only faster but also allows detection and marking of duplicate items - a feature unavailable when verifying email addresses one by one.
In the following example, we verify an email address using the default options:
job, err := client.EmailVerification.Run(context.TODO(), "batman@gmail.com")
if err != nil {
panic(err)
}
// At this point the address has been verified: let's print its email verification
// result to the console.
entry := job.Entries[0]
fmt.Printf("Classification: %s, status: %s\n", entry.Classification, entry.Status)
// Classification: Deliverable (status: Success)As expected, each entry includes various additional details about the verified email address:
| Property | Description |
|---|---|
AsciiEmailAddressDomainPart |
The domain part of the email address, converted to ASCII if needed, with comments and folding white spaces stripped off. |
Classification |
The deliverability Classification value for this entry. |
CompletedOn |
The date this entry was completed, if available. |
Custom |
A custom, optional string that is passed back upon verification completion. To pass a custom value back and forth, invoke the RunEntry() / RunEntries() methods and set the Custom field of SubmitEntryConfig accordingly. |
DuplicateOf |
The zero-based index of the first occurrence of this email address in the parent Job, when the Status for this entry is Duplicate. Duplicated items only expose this value and any Custom values. |
EmailAddress |
The email address without any comments or folding white space. Returns null if the input data is syntactically invalid. |
EmailAddressDomainPart |
The domain part of the email address, without comments and folding white spaces. |
EmailAddressLocalPart |
The local part of the email address, without comments and folding white spaces. |
HasInternationalDomainName |
True if the email address has an international domain name. |
HasInternationalMailboxName |
True if the email address has an international mailbox name. |
Index |
The index of this entry within its Job container. This property is primarily useful when the API returns a filtered view of the items. |
InputData |
The input string being validated. |
IsDisposableEmailAddress |
True if the email address comes from a disposable email address (DEA) provider. What is a disposable email address? |
IsFreeEmailAddress |
True if the email address comes from a free email address provider (e.g., Gmail, Yahoo, Outlook/Hotmail). |
IsRoleAccount |
True if the local part of the email address is a well-known role account. |
Status |
The deliverability Status value for this entry. |
Suggestions |
Potential corrections for the input data, when Verifalia identifies possible typos during the verification process. |
SyntaxFailureIndex |
The position of the character in the email address that caused syntax validation to fail, if applicable. |
Here's another example showing some of the additional result details provided by Verifalia, along with the use of the RunEntry() method, which accepts
a SubmitEntryConfig instance:
job, err := client.EmailVerification.RunEntry(context.TODO(),
emailverification.SubmitEntryConfig{
InputData: "bat[man@gmal.com",
Custom: "cus-123",
})
if err != nil {
panic(err)
}
// At this point the address has been verified: let's print its email verification
// result to the console.
entry := job.Entries[0]
fmt.Printf("Classification: %s\n", entry.Classification)
fmt.Printf("Status: %s\n", entry.Status)
fmt.Printf("Custom value: %s\n", entry.Custom)
if entry.SyntaxFailureIndex != nil {
fmt.Printf("Syntax failure index: %d\n", *entry.SyntaxFailureIndex)
}
if entry.Suggestions != nil {
fmt.Println("Suggestions:")
for _, suggestion := range entry.Suggestions {
fmt.Printf("- %s\n", suggestion)
}
}
// Classification: Undeliverable
// Status: InvalidCharacterInSequence
// Syntax failure index: 3
// Suggestions:
// - batman@gmail.comTo verify a list of email addresses instead of a single address, use either the RunStrings() / RunStringsWithOptions()
methods that accept an array with the strings to verify, or the RunEntries() / RunEntriesWithOptions() methods,
which accept an array of SubmitEntryConfigs. If the email addresses are originally stored in a file, you can simply
upload the file and have Verifalia automatically import and verify it - see the next section for details.
Here's an example showing how to verify an array of email addresses:
job, err := client.EmailVerification.RunStrings(context.TODO(),
[]string{
"batman@gmail.com",
"steve.vai@best.music",
"samantha42@yahoo.it",
})
if err != nil {
panic(err)
}
fmt.Printf("Job ID: %s\n", job.ID)
for _, entry := range job.Entries {
fmt.Printf("- %s => %s (%s)\n", entry.InputData, entry.Classification, entry.Status)
}
// Job Id: 290b5146-eeac-4a2b-a9c1-61c7e715f2e9
// - batman@gmail.com => Deliverable (Success)
// - steve.vai@best.music => Undeliverable (DomainIsMisconfigured)
// - samantha42@yahoo.it => Deliverable (Success)This library includes support for submitting and validating files containing email addresses, including:
- Plain text files (.txt), with one email address per line
- Comma-separated values (.csv), tab-separated values (.tsv), and other delimiter-separated value files
- Microsoft Excel spreadsheets (.xls and .xlsx)
To upload and verify a file, use either the RunFile() / RunFileWithOptions() methods, passing an os.File,
or the RunFileReader() / RunFileReaderWithOptions() methods which accept an io.Reader. With the *WithOptions() variants
you can also specify the starting and ending rows to process, the column, sheet index, line ending, and delimiter - depending
on the nature of the submitted file. See RunFileOptions in the source code to learn more.
For example, here's how to verify a text file containing one email address per line:
file, err := os.Open("emails.txt")
if err != nil {
panic(err)
}
job, err := client.EmailVerification.RunFile(context.TODO(), file)
// ...To set more advanced options, including those governing the import process of workbooks with multiple sheets and columns,
pass a RunFileOptions instance to the RunFileWithOptions() method and specify the sheet to process and the range of
data to import:
file, err := os.Open("that-file.xlsx")
if err != nil {
panic(err)
}
job, err := client.EmailVerification.RunFileWithOptions(context.TODO(),
file,
emailverification.RunFileOptions{
SubmitFileOptions: emailverification.SubmitFileOptions{
StartingRow: 1,
Column: 5,
Sheet: 3,
SubmitOptions: emailverification.SubmitOptions{
Quality: emailverification.QualityHigh,
},
},
})
// ...Here's another example showing how to submit an io.Reader instance while specifying the MIME content type of the file.
The content type is automatically determined from the file extension when you pass a FileInfo instance:
var fileReader io.Reader = ... // TODO: Acquire the input data somehow
job, err := client.EmailVerification.RunFileReaderWithOptions(context.TODO(),
fileReader,
emailverification.RunFileOptions{
SubmitFileOptions: emailverification.SubmitFileOptions{
ContentType: rest.ContentTypeTextPlain, // text/plain
},
})
// ...When submitting one or more email addresses for verification, you can specify several options that affect both the behavior of the Verifalia processing engine and the verification flow from the API consumer's perspective.
Verifalia offers three distinct quality levels - Standard, High, and Extreme - which determine how the email
verification engine handles temporary undeliverability issues, slower mail exchangers, and other potentially transient
problems that can affect verification result quality; you can specify the desired quality level for your email verification
through the options parameter of the Run*WithOptions() methods. Here's an example showing how to verify an email
address using the High quality level:
job, err := client.EmailVerification.RunWithOptions(context.TODO(),
"batman@gmail.com",
emailverification.RunOptions{
SubmitOptions: emailverification.SubmitOptions{
Quality: emailverification.QualityHigh, // High quality level
},
})
// ...The Run*WithOptions() methods that accept multiple email addresses allow you to specify how to handle duplicate entries
within the same input set. Verifalia supports a Safe deduplication mode, which strictly adheres to older IETF standards,
and a Relaxed mode that aligns with what's commonly found in today's mail server configurations.
In this example, we show how to import and verify a list of email addresses while marking duplicate entries using the Relaxed deduplication mode:
file, err := os.Open("that-file.xlsx")
if err != nil {
panic(err)
}
job, err := client.EmailVerification.RunFileWithOptions(context.TODO(),
file,
emailverification.RunFileOptions{
SubmitFileOptions: emailverification.SubmitFileOptions{
SubmitOptions: emailverification.SubmitOptions{
Deduplication: emailverification.DeduplicationRelaxed, // Relaxed deduplication mode
},
},
})
// ...Verifalia automatically deletes completed email verification jobs according to the data retention policy defined at the account level, which can be overridden at the user level. You can configure these settings in the Verifalia client area.
You can also specify a per-job data retention policy that governs the time-to-live of a submitted email verification job.
To do this, use the Run*WithOptions() methods and set the Retention field of the options parameter accordingly.
Here's how to set a data retention policy of 10 minutes while verifying an email address:
job, err := client.EmailVerification.RunWithOptions(context.TODO(),
"batman@gmail.com",
emailverification.RunOptions{
SubmitOptions: emailverification.SubmitOptions{
Retention: 10 * time.Minute,
},
})
// ...As mentioned, the Run*() methods submit an email verification job to Verifalia and wait for its completion. The entire
process may take some time depending on your Verifalia account plan, the number of email addresses in the submission, the
specified quality level, and other network factors including the latency of mail exchangers under test.
While waiting for a verification job to complete, the library automatically polls the underlying Verifalia API until results are ready. By default, it leverages the long polling mode introduced with Verifalia API v2.4, which minimizes the number of requests and delivers verification results faster.
In certain scenarios (such as microservice architectures), it may be preferable to avoid waiting for job completion and
simply queue the job instead. In this case, the library would return just the job overview (not its verification results),
and you would need to retrieve the verification results using either the Get() / GetWithOptions() methods.
To do this, use the Submit*() methods to queue your email verification job:
file, err := os.Open("that-file.xlsx")
if err != nil {
panic(err)
}
job, err := client.EmailVerification.SubmitFileWithOptions(context.TODO(),
file,
emailverification.SubmitFileOptions{
SubmitOptions: emailverification.SubmitOptions{
Quality: emailverification.QualityExtreme,
Retention: 2 * time.Hour,
},
}
)
fmt.Printf("Status: %s\n", job.Status)
// Status: InProgressFor jobs with a large number of email addresses, it can be useful to track progress as addresses are processed by the
Verifalia email verification engine. To do this, create an instance of the WaitOptions struct and provide a function
that receives progress notifications through the Progress field.
Here's how to define a progress notification handler that displays the progress percentage of a submitted job to the console:
file, err := os.Open("that-file.xlsx")
if err != nil {
panic(err)
}
job, err := client.EmailVerification.RunFileWithOptions(context.TODO(),
file,
emailverification.RunFileOptions{
WaitOptions: emailverification.WaitOptions{
Progress: func(job emailverification.Job) {
if job.Progress != nil {
fmt.Printf("Completion: %0.2f%%, ETA: %v\n", job.Progress.Percentage*100, job.Progress.EstimatedTimeRemaining)
}
},
},
},
)
// ...Along with each email verification job, you can specify a URL that Verifalia will invoke (POST) once the job completes. This URL must use the HTTPS or HTTP scheme and be publicly accessible over the Internet. To learn more about completion callbacks, please see https://verifalia.com/developers#email-validations-completion-callback.
To specify a completion callback URL, call any of the Run*WithOptions() methods and set the CompletionCallback of
its options parameter accordingly:
completionUrl, err := url.Parse("https://your-website-here/foo/bar")
if err != nil {
panic(err)
}
job, err := client.EmailVerification.RunStringsWithOptions(context.TODO(),
[]string{"batman@gmail.com", "zula.hendricks@marines.com"},
emailverification.RunOptions{
SubmitOptions: emailverification.SubmitOptions{
CompletionCallback: emailverification.CompletionCallbackOptions{
URL: *completionUrl,
},
},
},
)
// ...Note that completion callbacks are invoked asynchronously, and it may take several seconds for your callback URL to be invoked.
You can retrieve an email verification job using the Get() or GetOverview() methods, which return a Job or
an Overview instance, respectively, for the specified email verification job. When you call either method, the
library fetches a fresh snapshot of the job’s current state. If the job is still in progress, the methods return
immediately without waiting for completion. Alternatively, you can use the GetWithOptions() or GetOverviewWithOptions() methods to specify how long the
Verifalia API should wait for the job to complete on the server side before returning a response.
If you want the library to automatically poll the Verifalia API until the job is complete, use the WaitForCompletion()
or WaitForCompletionWithOptions() method.
Here's an example showing how to retrieve a job by its ID and automatically wait for completion when necessary:
jobID := "7d97711d-a77a-452a-b4ef-2f4c51b72a4c"
job, err := client.EmailVerification.Get(context.TODO(), jobID)
if err != nil {
panic(err)
}
job, err = client.EmailVerification.WaitForCompletion(context.TODO(), *job)
// ...This library allows you to export the entries of a completed email verification job in different output formats through
the ExportEntries() method. This generates a human-readable representation of the verification results.
WARNING: While the output schema (columns/labels/data format) is fairly complete, you should always consider it subject to change. Use the
Run*()orGet*()methods instead if you need to rely on a stable output schema.
Here's an example showing how to export a given email verification job as a comma-separated values (CSV) file:
jobID := "722c2fd8-8837-449f-ad24-0330c597c993"
result, err := client.EmailVerification.ExportEntries(context.TODO(),
jobID,
emailverification.ExportedEntriesFormatCsv)
if err != nil {
panic(err)
}
defer result.Close()
// Create the file
out, err := os.Create("output.csv")
if err != nil {
panic(err)
}
defer out.Close()
// Stream the result directly to the file
_, err = io.Copy(out, result)
if err != nil {
panic(err)
}Verifalia automatically deletes completed jobs according to a configurable data-retention policy (see the related section),
but we strongly recommend that you delete completed jobs as soon as possible for privacy and security reasons. To do this,
invoke the Delete() method, passing the job ID you wish to remove:
jobID := "722c2fd8-8837-449f-ad24-0330c597c993"
err := client.EmailVerification.Delete(context.TODO(), jobID)
if err != nil {
panic(err)
}Once deleted, a job is permanently removed and there is no way to retrieve its email verification results.
For management and reporting purposes, you may want to obtain a detailed list of your past email verification jobs. This
SDK library allows you to do this through the List() and ListWithOptions() methods, which allow asynchronous iteration
over a collection of Overview instances through a channel.
Here's how to iterate over your jobs from most recent to oldest:
results := client.EmailVerification.ListWithOptions(context.TODO(),
emailverification.ListOptions{
Direction: common.DirectionBackward,
})
for result := range results {
if result.Error != nil {
panic(result.Error)
}
overview := result.JobOverview
fmt.Printf("ID: %s, status: status: %s, entries: %d\n",
overview.ID,
overview.Status,
overview.NoOfEntries)
}
// Prints out something like:
//
// Id: a7784f9a-86d4-436c-b8e4-f72f2bd377ac, status: InProgress, entries: 9886
// Id: 86d57c00-147a-4736-88cc-c918260c67c6, status: Completed, entries: 1
// Id: 594bbb0f-6f12-481c-926f-606cfefc1cd5, status: Completed, entries: 1
// Id: a5c1cd5b-39cc-43bc-9a3a-ee4a0f80ee6d, status: InProgress, entries: 226
// Id: b6f69e30-60dd-4c21-b2cb-e73ba75fb278, status: Completed, entries: 12077
// Id: 5e5a97dc-459f-4edf-a607-47371c32aa94, status: Deleted, entries: 1009
// ...The ListWithOptions() method also allows you to filter the email verification jobs returned by the Verifalia API through
the same options` argument. You can filter by submission date, owner, and job status.
Here's how to repeat the listing operation shown above, this time returning only jobs for a specific user and date range:
since := time.Date(2025, 7, 1, 0, 0, 0, 0, nil)
until := time.Date(2025, 7, 9, 0, 0, 0, 0, nil)
results := client.EmailVerification.ListWithOptions(context.TODO(),
emailverification.ListOptions{
CreatedOn: common.NewDateBetweenPredicate(since, until),
Direction: common.DirectionBackward,
OwnerID: common.NewStringEqualityPredicate("50173acd-9ed2-4298-ba7f-8ccaeed48deb"),
})
for result := range results {
// ...
}To manage Verifalia credits for your account, use the Credit field exposed by the Client instance created above. Like
the previous topic, in the following sections we'll examine the most common operations. We strongly recommend exploring
the library and consulting the godoc for other capabilities.
One of the most common tasks you may need to perform is retrieving the available number of free daily credits and credit
packs. To do this, use the GetBalance() method, which returns a Balance object:
balance, err := client.Credit.GetBalance(context.TODO())
if err != nil {
panic(err)
}
fmt.Printf("Credit packs: %0.0f\n", balance.CreditPacks)
fmt.Printf("Free daily credits: %0.0f (will reset in %v)\n", balance.FreeCredits, balance.FreeCreditsResetIn)
// Prints out something like:
//
// Credit packs: 956.332
// Free daily credits: 128.66 (will reset in 09:08:23)To add credit packs to your Verifalia account, visit https://app.verifalia.com/#/credits/add.
To monitor and forecast credit consumption for your account, the ListDailyUsages() method allows you to retrieve statistics
about historical credit usage, returning an asynchronously iterable collection of DailyUsage instances through a channel,
while the sibling ListDailyUsagesWithOptions() method also allows you to apply filters to the results. Elements are
returned only for dates where consumption (of free credits, credit packs, or both) occurred.
Here's how to retrieve daily credit consumption for the last thirty days:
results := client.Credit.ListDailyUsagesWithOptions(context.TODO(),
credit.ListDailyUsageOptions{
Date: common.NewDateBetweenPredicate(time.Now().Add(-30*24*time.Hour), time.Now()),
})
for result := range results {
if result.Error != nil {
panic(result.Error)
}
fmt.Printf("Date: %s\n", result.Item.Date.Format("2006-01-02"))
fmt.Printf("- credit packs: %0.0f\n", result.Item.CreditPacks)
fmt.Printf("- free credits: %0.0f\n", result.Item.FreeCredits)
}
// Prints out something like:
//
// Date: 2025-06-23
// - credit packs: 1965.68
// - free daily credits: 200
// Date: 2026-06-21
// - credit packs: 0
// - free daily credits: 185.628
// Date: 2025-06-20
// - credit packs: 15.32
// - free daily credits: 200
// ...The Verifalia API provides the ability to manage users in your Verifalia account, as well as their security and configuration settings. Each user has unique login credentials and can submit, view, and manage their own private email-verification jobs while sharing the same account balance. This makes it easy to separate activities for team members, clients (if you're reselling our email verification service), or other API consumers (such as apps and websites using our email verification widget).
To manage users for your Verifalia account, use the User property exposed by the Client instance created above.
Each user can be one of these types:
- Administrator: Has complete, unrestricted access to the Verifalia account
- Standard user: Has flexible, granular permissions, ideal for coworkers or API access
- Browser app: Designed for public-facing web applications and our embeddable widget; uses passwordless authentication and has fixed, limited permissions restricted to email verification only
Where applicable, the API also allows configuring specific settings for each user, including authentication methods and secondary authentication factors, permissions, firewall rules, CAPTCHA/bot detection settings, throttling rules, data retention settings, and trusted origins.
This SDK allows you to list the users in your Verifalia account by invoking either the List() or ListWithOptions()
methods, which return an asynchronously iterable collection of Overview objects containing the basic information
for each user.
for result := range client.User.List(ctx) {
if result.Error != nil {
panic(result.Error)
}
fmt.Printf("User ID: %s\n", result.Item.ID)
fmt.Printf("- display name: %s\n", result.Item.DisplayName)
fmt.Printf("- type: %s\n", result.Item.Type)
}
// Prints out something like:
//
// User ID: ed49bbce-77d1-4af3-8a15-f25e20fff123
// - display name: Walter White
// - type: Administrator
// User ID: 8eaadc82-6bf5-46b2-8ac3-f62dddfeb47e
// - display name: Alvaro Vitali
// - type: StandardTo retrieve the complete configuration details for each user, invoke the Get() method exposed by the User field
mentioned earlier, which returns an instance of the User type.
In the example below, we retrieve a user by their ID, then print some of their configuration settings to the console:
userID := "7bbe92e6-b75b-4fad-a819-d8ed30f093fd"
usr, err := client.User.Get(context.TODO(), userID)
if err != nil {
panic(err)
}
// Display name
fmt.Printf("Display name: %s\n", usr.DisplayName)
// Active / Inactive status
fmt.Printf("IsActive: %v\n", usr.IsActive)
// Default settings
fmt.Printf("Default data retention period: %v\n", usr.Defaults.Retention)
// Throttling rules
fmt.Printf("Throttling rules:\n")
if usr.Throttling != nil && usr.Throttling.Rules != nil {
for _, rule := range *usr.Throttling.Rules {
fmt.Printf("- %d per %s, scope: %s\n",
rule.Limit,
rule.Period,
rule.Scope)
}
}
// Prints out something like:
//
// Display name: Zula Hendricks
// IsActive: true
// Default data retention period: 05:30:00
// Throttling rules:
// - 3 per Minute, scope: IPAddress
// - 100 per Day, scope: GlobalWe strongly recommend exploring the User type and examining the exposed properties for other configuration settings.
To create a new user, invoke the Create() method exposed by the User field, passing a CreateConfig instance with
the configuration settings for the user you want to add.
In the example below, we add a new standard user named James McGill who has username-password authentication and can read the account balance and operate on his own email verifications:
createConfig := user.CreateConfig{}
createConfig.DisplayName = "James McGill"
createConfig.IsActive = true
createConfig.Type = user.TypeStandard
createConfig.Authentication = &user.AuthenticationConfig{
Password: &user.PasswordAuthenticationConfig{
IsEnabled: true,
Username: "jimmy",
Password: "5058425662",
},
}
createConfig.Authorization = &user.AuthorizationSettings{
Rules: []string{
"credits:read-balance",
"email-verifications:*:own",
},
}
newUser, err := client.User.Create(context.TODO(), createConfig)
if err != nil {
panic(err)
}
fmt.Printf("User ID: %s\n", newUser.ID)To update a user, invoke the Update() method of the User field and specify the ID of the user along with an UpdateConfig
instance with the changes to apply.
For instance, here's how to update the display name of the user we created in the previous section:
updateConfig := user.NewUpdateConfig()
updateConfig.ReplaceDisplayName("Saul Goodman")
err = client.User.Update(context.TODO(),
newUser.ID,
updateConfig)
if err != nil {
panic(err)
}To avoid conflicts, you can specify the ETag of the user so that the Verifalia API can detect mid-air edit collisions
and avoid updating the target user if it has a newer version. To do this, use the UpdateWithOptions() method and specify
the ETag value as the IfMatch field:
err = client.User.UpdateWithOptions(context.TODO(),
newUser.ID,
updateConfig,
user.UpdateOptions{
IfMatch: newUser.Etag,
})
if err != nil {
panic(err)
}Deleting a user is as simple as invoking the Delete() method of the User field, specifying the ID of the user to remove:
userID := "6554d4a3-2c7f-4de8-8d8e-f1ae36486c06"
err = client.User.Delete(context.TODO(), userID)
if err != nil {
panic(err)
}Each standard user can have one or more X.509 client certificates associated with them. These certificates can be used for TLS mutual authentication (also known as Client Certificate Authentication).
Similar to the objects mentioned above, to manage client certificates for your Verifalia account, use the ClientCertificate
field exposed by the Client instance created above.
To list the X.509 client certificates associated with a specific user, invoke the List() method of the ClientCertificate
field to retrieve an asynchronously iterable collection of ClientCertificate objects containing information about each
certificate:
userID := "6554d4a3-2c7f-4de8-8d8e-f1ae36486c06"
results := client.ClientCertificate.List(context.TODO(), userID)
for result := range results {
fmt.Printf("%s\n", result.Item.Subject)
fmt.Printf("- thumbprint: %s\n", result.Item.Thumbprint)
fmt.Printf("- validity: since %v until %v\n", result.Item.NotBefore, result.Item.NotAfter)
}
// Prints out something like:
//
// O=Gray Matter, S=NM, C=US
// - thumbprint: 74c0fa6f23e34efc945cb96511487b0764e0e29d
// - validity: since 2024-11-16 18:24:10 +0000 UTC until 2029-11-15 18:24:10 +0000 UTCTo upload and bind a new certificate to a user, invoke the Create() method exposed by the ClientCertificate field.
It accepts an io.Reader with the content of the certificate file to upload, which must be either a base64-encoded
format (commonly with .pem, .crt, or .cer extensions) or a binary (DER) format (commonly with .der or .cer extensions).
For enhanced security and compliance with RFC 5280, Verifalia only accepts X.509 client certificates that include the Extended Key Usage extension id-kp-clientAuth (OID 1.3.6.1.5.5.7.3.2).
The method returns an instance of the ClientCertificate type, which contains details about the created certificate:
userID := "6554d4a3-2c7f-4de8-8d8e-f1ae36486c06"
certFile, err := os.Open("/home/wwhite/my-cert.pem")
if err != nil {
panic(err)
}
newCert, err := client.ClientCertificate.Create(context.TODO(),
userID,
certFile)
if err != nil {
panic(err)
}
fmt.Printf("ID: %s\n", newCert.ID)
fmt.Printf("- public key: %s\n", newCert.PublicKey)
fmt.Printf("- validity: since %v until %v\n", newCert.NotBefore, newCert.NotAfter)
// Prints out something like:
//
// ID: 3997d2fe-69af-43f7-9667-91204a8e7f8c
// - public key: 87185105bfad934cf445a0f77a41a73b20309e8da9cb417771d488444fed55ec
// - validity: since 2024-11-16 18:24:10 +0000 UTC until 2029-11-15 18:24:10 +0000 UTCTo delete a client certificate from Verifalia, invoke the Delete() method of the ClientCertificate field:
err := client.ClientCertificate.Delete(context.TODO(),
"6554d4a3-2c7f-4de8-8d8e-f1ae36486c06", // ID of the user
newCert.ID)
if err != nil {
panic(err)
}A contact method in Verifalia is a way for the system to send notifications to a user. Notifications cover everything from system alerts (such as expiring client certificates) to commercial document updates and news.
To manage contact methods for your Verifalia account, use the ContactMethod field exposed by the Client instance
created above.
To list the contact methods associated with a specific user, invoke the List() method of the ContactMethod field to
retrieve an asynchronously iterable collection of ContactMethod objects containing information about each contact method.
userID := "6554d4a3-2c7f-4de8-8d8e-f1ae36486c06"
for result := range client.ContactMethod.List(ctx, userID) {
if result.Error != nil {
panic(result.Error)
}
fmt.Printf("%s (ID: %s)\n", result.Item.DisplayName, result.Item.ID)
if result.Item.Type == contactmethod.TypeEmail {
fmt.Printf("- email: %s\n", result.Item.EmailAddress)
}
}
// Prints out something like:
//
// Walter White (ID: 04715cde-7910-4445-8d87-b85809267928)
// - email: walt@a1acarwash.com
// Mr. Heisenberg (ID: 07414602-8987-4463-8b51-f101e488f4af)
// - email: heisenberg@bluesky.shopTo retrieve a single contact method, invoke the Get() method of the ContactMethod field, which accepts the ID of the
user and the ID of the contact method, and returns an instance of the ContactMethod type:
userID := "f78d04a8-ee07-4b48-819a-8282d606acdf"
contactMethodID := "4e1d503f-9f54-438c-ba88-7414c4426045"
contactMethod, err := client.ContactMethod.Get(context.TODO(),
userID,
contactMethodID);
if err != nil {
panic(err)
}
fmt.Printf("%s\n", contactMethod.DisplayName)
// ...To create a contact method for a user, invoke the Create() method of the ContactMethod field and specify the
configuration details for the new object. The method returns a ContactMethod object with details about the newly
created item:
userID := "21d5aa6e-417c-4e27-b71c-2d68151bb974"
contactMethod, err := client.ContactMethod.Create(ctx,
userID,
contactmethod.CreateConfig{
DisplayName: "Luigi Schroeder",
Type: contactmethod.TypeEmail,
EmailAddress: "reder28@gmail.com",
})
if err != nil {
panic(err)
}
fmt.Printf("Contact ID: %s\n", contactMethod.ID)Once a contact method is created, it is inactive and needs to be activated before being available for use. The activation process involves a manual step where the recipient receives an activation code that must be provided to the Verifalia API.
To activate a contact method, invoke the Activate() method of the ContactMethod field, specifying the target user ID,
the ID of the contact method you wish to activate, and the activation code automatically received when the contact method
was created:
userID := "f78d04a8-ee07-4b48-819a-8282d606acdf"
contactMethodID := "4e1d503f-9f54-438c-ba88-7414c4426045"
activationCode := "abcde12345"
err := client.ContactMethod.Activate(context.TODO(),
userID,
contactMethodID,
activationCode)
if err != nil {
panic(err)
}To update a contact method, invoke the Update() method of the ContactMethod field and pass an UpdateConfig
instance with the changes to apply.
For instance, here's how to update the display name of the contact method we created in the previous section:
userID := "f78d04a8-ee07-4b48-819a-8282d606acdf"
contactMethodID := "4e1d503f-9f54-438c-ba88-7414c4426045"
updateConfig := contactmethod.NewUpdateConfig()
updateConfig.ReplaceDisplayName("Gigi Reder")
err := client.ContactMethod.Update(context.TODO(),
userID,
contactMethodID,
updateConfig)
if err != nil {
panic(err)
}To delete a contact method, invoke the Delete() method of the ContactMethod field, specifying the ID of the user and
the ID of the contact method to remove:
userID := "f78d04a8-ee07-4b48-819a-8282d606acdf"
contactMethodID := "4e1d503f-9f54-438c-ba88-7414c4426045"
err := client.ContactMethod.Delete(context.TODO(),
userID,
contactMethodID)
if err != nil {
panic(err)
}This section lists the changelog for the current major version of the library. For older versions, please see the project releases. For clarity, logs for build and revision updates are excluded.
Released October 2025
- Added support for Verifalia API v2.7.
- Added support for managing users and browser apps within a Verifalia account, including their security and configuration settings.
- Added support for managing user contact methods.
- Added support for managing X.509 TLS client certificates associated with Verifalia users.
- Added support for external completion callbacks when submitting email verifications.
- Added the ability to filter email verification jobs using predicates.
- Added the ability to retrieve credit usage over a specified time period.
- Added support for bearer token authentication and multi-factor authentication (MFA) using a custom TOTP provider.
- Added support for
problem+jsonerror format. - Introduced
NewClientWithConfig()for creating clients with custom, advanced configuration settings. - Refactored the module to have zero external dependencies.
- Improved how the underlying REST client balances and rotates API endpoints.
- Enhanced documentation throughout the SDK.
- Updated code samples.
- Promoted
context.Contextfields in*Configand*Optionsstructs to be the first parameters in method signatures; removed all*WithContext()methods. - Credit balance is now returned as a
float64instead ofbig.Decimal. - The
emailvalidationpackage has been renamed toemailverification. - Several methods have been renamed for improved clarity and consistency.