How to Create and Send vCards with Go

October 02, 2026
Written by
Reviewed by

How to Create and Send vCards with Go

More than likely you've shared a friend's contact details with someone. When you did that, you likely copied their name and phone number or email address, etc from your phone's contacts app into a message using your messaging app of choice, e.g., Signal, WhatsApp, Messenger, SnapChat etc.

While it might seem quick and easy — despite repeatedly switching between apps to copy everything you need — it's actually a pretty ineffective way of sharing contacts. A far better way is to send a vCard (Virtual Contact File).

If you're not familiar with it, vCard is a data format which can store a lot of information about people and organisations, such as their name, phone numbers, email addresses, postal address(es), anniversaries, and photos.

What's more they're supported by:

  • All major desktop and mobile operating systems
  • The most common email services and apps, such as Apple Mail, Gmail, and Thunderbird
  • The contact apps which ship with the major operating systems

What's more, you can send a contact's completed details in one go — in a well-structured and organised way. That's easier for everyone involved.

If this sounds like something you're interested in, in this short Go-focused tutorial, you'll learn how to create them, and how to then send them via SMS powered by Twilio's Programmable Messaging API.

Prerequisites

To follow along with this tutorial, you will need the following

  • Go installed on your development machine
  • Your preferred Go editor or IDE, such as Neovim or Visual Studio Code
  • A Twilio account (either free or paid). Create one now if you don't already have one.
  • A Twilio phone number that can send SMS
  • A mobile/cell phone that can receive SMS

Create a new Go project

Let's get started building the code by creating a new Go project and initialising it as a Go module. To do that, run the commands below.

mkdir send-vcards-in-go
cd send-vcards-in-go
go mod init

Install the required dependencies

Next, you need to install the project's dependencies. These are:

  • GoDotEnv: This package creates environment variables from a dotenv ( .env) file, letting us keep our application's configuration separate from its code
  • go-vcard: This package simplifies reading and writing valid vCard files
  • Twilio's Go Helper Library (SDK): This package simplifies sending SMS with Twilio

To install them, run the command below.

go get \
    github.com/emersion/go-vcard \
    github.com/twilio/twilio-go \
    github.com/joho/godotenv
If you're using Microsoft Windows, replace the backslash in the command above with a caret (^).

Set the required environment variables

Now, we need to set some environment variables, so that the application can make authenticated requests to Twilio's Programmable Messaging API, and that it knows who the SMS sender and receiver are.

Start by creating a file named .env in the project's top-level directory with the following content.

TO_PHONE_NUMBER=
TWILIO_ACCOUNT_SID=
TWILIO_ASSET_URL=
TWILIO_AUTH_TOKEN=
TWILIO_PHONE_NUMBER=

After that, open the Twilio Console and go to the Account Info panel.

Twilio console with account information, balance, and project details displayed on a desktop browser.
Twilio console with account information, balance, and project details displayed on a desktop browser.

There, copy your Account SID, Auth Token, and Twilio phone number. Then, paste them into .env as the values of TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, and TWILIO_PHONE_NUMBER, respectively. Then, set TO_PHONE_NUMBER to your mobile/cell phone number — formatted in E.164 format, e.g., "+61493123456".

Write the code to create a vCard file

With the setup now complete, it's time to write the Go code. In the project's top-level directory, create a file named create-vcard.go, then paste the code below into the file.

package main

import (
	"log"
	"os"

	"github.com/emersion/go-vcard"
)

func main() {
	card := vcard.Card{
		vcard.FieldVersion: []*vcard.Field{{Value: "4.0"}},
	}

	card.AddAddress(&vcard.Address{
		StreetAddress: "1 Trafalgar Square",
		Locality:      "London",
		Region:        "London",
		PostalCode:    "WC2N",
		Country:       "United Kingdom",
	})
	card.Add(vcard.FieldFormattedName, &vcard.Field{
		Value: "Joe Bloggs",
	})
	card.AddName(&vcard.Name{
		FamilyName: "Bloggs",
		GivenName:  "Joe",
	})
	card.Add(vcard.FieldURL, &vcard.Field{
		Value:  "https://example.org",
		Params: vcard.Params{vcard.ParamType: {vcard.TypeHome}, vcard.ParamPreferred: {"1"}},
	})
	card.Add(vcard.FieldTelephone, &vcard.Field{
		Value: "tel:+442012345678",
		Params: vcard.Params{
			vcard.ParamType: {
				vcard.TypeCell,
				vcard.TypeHome,
			},
			vcard.ParamPreferred: {"1"},
		},
	})
	card.Add(vcard.FieldEmail, &vcard.Field{
		Value: "user@example.org",
		Params: vcard.Params{
			vcard.ParamType: {
				vcard.TypeHome,
			},
			vcard.ParamPreferred: {"1"},
		},
	})

	var filePermissions os.FileMode = 0644
	f, err := os.OpenFile(
		"vcard.vcf",
		os.O_WRONLY|os.O_CREATE|os.O_TRUNC,
		filePermissions,
	)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	if err := vcard.NewEncoder(f).Encode(card); err != nil {
		log.Fatalf("unable to write vCard. Reason: %s", err.Error())
	}
}

The main() function initialises a new Card object, which models a vCard, and sets its version, along with an address, name, URL, telephone number, and email address. The code makes use of a number of constants, which you can find in card.go in the project's GitHub repository.

Feel free to change any of the dummy data.

After that, it creates a new file named vcard.vcf in the current directory and writes the vCard data to the file. If it's unable to do so, because, for example, the current directory isn't writable, the code prints the failure reason to the terminal and exits.

Run the code

With the code ready, run the command below to create the vCard file.

go run create-vcard.go

Assuming that you kept the dummy data in the code above, if you look in vcard.vcf you'll find that it looks like the following:

BEGIN:VCARD
VERSION:4.0
ADR:;;1 Trafalgar Square;London;London;WC2N;United Kingdom
EMAIL;PREF=1;TYPE=home:user@example.org
FN:Joe Bloggs
N:Bloggs;Joe;;;
TEL;PREF=1;TYPE=cell;TYPE=home:tel:+442012345678
URL;PREF=1;TYPE=home:https://example.org
END:VCARD

Make the vCard file publicly accessible

Before we can send the vCard via SMS, we need to make it publicly accessible on the internet. This is so that Twilio can include it with the SMS when it's sent.

There are numerous ways that we can make a file publicly accessible, including an AWS S3 Bucket, putting it in a publicly accessible directory on a webserver, or using a service such as DigitalOcean Spaces. However, each of these require some manual setup and an account with the respective service or server.

So, we'll use Twilio Assets instead as it's bundled with every Twilio account. If you're not familiar with Twilio Assets, it's a static file hosting service we can use to quickly upload and serve files, such as MP3 audio files.

In the Twilio Console, navigate through Builder tools > Functions & Assets > Services. There, click Create Service, enter a name for the new service, and click Next.

Twilio console prompts user to enter a service name for serverless domain creation.

Then, click "Add +", and click Upload File. Pick the file from your filesystem. Set Visibility as Public, and click Upload.

Screenshot of Twilio console showing the upload asset file dialog with various options.

In the logs, you'll see "Asset <your file's name> created" when the file is uploaded.

Log showing creation and completion of vcard.vcf asset on Sep 29, 2026 with timestamps.

Press Deploy All and wait for the service to deploy, which should take less than a minute. When deployed, expand the Assets menu and click the vertical ellipsis button next to the name of the file that you just uploaded. Now, click "Copy URL".

Screenshot of the Twilio console showing the Functions feature and account balance.

Now, paste the URL that you just copied as the value of TWILIO_ASSET_URL in .env.

Write the code to send a vCard

Now, let's write the code to send the vCard. Create another Go file in the project's top-level directory named send-vcard.go and paste the code below into the file.

package main

import (
	"fmt"
	"log"
	"os"
	"github.com/joho/godotenv"

	twilio "github.com/twilio/twilio-go"
	openapi "github.com/twilio/twilio-go/rest/api/v2010"
)

func main() {
	err := godotenv.Load()
	if err != nil {
		log.Fatal("Error loading .env file")
	}

	client := twilio.NewRestClient()
	params := &openapi.CreateMessageParams{}
	params.SetTo(os.Getenv("TO_PHONE_NUMBER"))
	params.SetFrom(os.Getenv("TWILIO_PHONE_NUMBER"))
	params.SetBody("Ahoy! Please find my contact details below!")
	params.SetMediaUrl([]string{os.Getenv("TWILIO_ASSET_URL")})
	_, err = client.Api.CreateMessage(params)
	if err != nil {
		fmt.Println(err.Error())
	} else {
		fmt.Println("SMS sent successfully!")
	}
}

The code loads the environment variables from .env, and then instantiates a new Twilio.RestClient object, transparently retrieving your Twilio Account SID and Auth Token from the respective environment variables; Twilio.RestClient is the core Go object for making RESTful calls to Twilio's APIs.

Then, it sets several SMS parameters, the sender, recipient, message body, and link to the vCard file (the media URL), and passes them to the call to client.Api.CreateMessage() to send the SMS.

Run the code

With the code complete, run the command below to send the vCard by SMS.

go run send-vcard.go

After the command's completed, you'll see "SMS sent successfully!" printed to the terminal, and you'll receive an SMS with a link to the vCard, similar to the screenshot below.

Smartphone screen showing a text message with a link to contact details from Twilio.

Open the link. You should see the vCard open in your phone's contact application, where you can then see all of the contained contact details.

That's how to create and send vCards with Go and Twilio

You've now learned how to create vCards, and how to send them via SMS, using Go and powered by Twilio's Programmable Messaging API. By doing so, you can save time and effort sharing contacts with friends when they ask you for them.

I hope that you've seen how they're much more effective and organised than sending details using either a messaging app or email. I've only touched on what vCard offers in this tutorial, so hope you will dive into the spec to see everything else on offer.

I'm excited to see what you build!

Matthew Setter is (primarily) the PHP, Go, and Rust editor on the Twilio Voices team. He’s also the author of Mezzio Essentials and Deploy with Docker Compose. You can find him at msetter[at]twilio.com. He's also on LinkedIn and GitHub.