Ir a la documentación
Go

client.Contacts

Cada método de este espacio de nombres: su firma, sus parámetros, lo que devuelve y un ejemplo.

Métodos

The workspace address book: people it has written to, plus anybody you save yourself.

Contacts.List

List the workspace contacts, most recently seen first

Alcancescontacts:readRecorre los resultados por páginas
Firma
List(ctx context.Context, opts ...openemail.RequestOption) (*openemail.Page, error)

Returns one page of the workspace address book, ordered by lastSeenAt with the most recent first and contacts that have never been mailed last. source says where a row came from: manual for a contact somebody saved, in the app or through Create, and auto for an address recorded when a member sent mail to it from the app composer. A saved contact stays manual when it is mailed later.

openemail.WithSource narrows the page to one origin, so a map with source set to manual is the contacts somebody saved on purpose and a map with source set to auto the ones the composer recorded. openemail.WithQ searches the name and the address.

This lists saved contacts only. ListPeople lists everyone the Contacts page in the app shows, the addresses seen in mail included, with thread counts.

Paging is keyset. openemail.WithLimit takes 1 to 200 and defaults to 50, and NextCursor goes back as openemail.WithCursor while HasMore is true. Never build a cursor yourself.

Contacts belong to the whole workspace rather than to any one address, so a key limited to particular addresses or domains reads and writes the same book as every other key. An app connected by a member who reaches only some addresses is refused with 422 capability_unsupported on addressAllowlist, on every contacts, audiences and broadcasts route.

Parámetros

openemail.WithLimitint

Rows per page, a whole number from 1 to 200. The server defaults to 50.

openemail.WithCursorstring

The NextCursor from the previous page. Never build one yourself.

openemail.WithSourcestring

manual, auto or form. Leave it out for the whole book.

openemail.WithQstring

Searches the name and the address, up to 200 characters. When nothing matches exactly on the first page, close spellings are returned instead, and the pages that follow keep matching the same way.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

A *openemail.Page with Items, HasMore and NextCursor. Each contact has email, name, source, notes, photoUrl and lastSeenAt.

Ejemplo

page, err := client.Contacts.List(ctx, openemail.WithSource("manual"), openemail.WithLimit(200))if err != nil {	return err} for _, contact := range page.Items {	fmt.Println(contact.String("name"), contact.String("email"))} fmt.Println(page.HasMore, page.NextCursor)

Notas

  • Mail sent through this API adds no contacts. Only sends from the app composer record recipients, and Create is the way to add one deliberately.

  • Every member of the workspace reads and writes the same book, so a contact saved by one person is visible to the rest.

  • A contact that has never been mailed has lastSeenAt null and sorts last, after every contact with a date.

  • Addresses are stored lower cased.

También disponible en

API
GET /contacts
TypeScript
contacts.list()
Python
contacts.list()
Ruby
contacts.list
PHP
contacts->list
Java
contacts().list
C#
Contacts.ListAsync
CLI
openemail contacts list

Contacts.ListAll

Collect the whole address book into one slice

Alcancescontacts:readRecorre los resultados por páginas
Firma
ListAll(ctx context.Context, opts ...openemail.RequestOption) ([]openemail.Object, error)

Follows NextCursor from page to page and returns with every contact in the workspace, most recently seen first and never-mailed contacts last. It takes the same source and q filters as List.

Everything is held in memory before the call returns, and an address book grows with every recipient the composer records. Prefer Iterate when you can stop early. limit sets the page size of each request, not the total.

Parámetros

openemail.WithSourcestring

manual, auto or form. Leave it out for the whole book.

openemail.WithQstring

Searches the name and the address, up to 200 characters. When nothing matches exactly on the first page, close spellings are returned instead, and the pages that follow keep matching the same way.

openemail.WithLimitint

Page size per request, from 1 to 200, defaulting to 50 on the server.

openemail.WithCursorstring

A cursor from an earlier page to start after.

openemail.WithAPIKeystring

Overrides the client's API key for every page of this walk.

Devuelve

A []openemail.Object holding every contact across all pages.

Ejemplo

saved, err := client.Contacts.ListAll(ctx, openemail.WithSource("manual"), openemail.WithLimit(200))if err != nil {	return err} for _, contact := range saved {	fmt.Println(contact.String("name"), contact.String("email"))}

Notas

  • A failure on any page fails the whole call, and the contacts already fetched are discarded.

También disponible en

API
GET /contacts
TypeScript
contacts.listAll()
Python
contacts.list_all()
Ruby
contacts.list_all
PHP
contacts->listAll
Java
contacts().listAll
C#
Contacts.ListAllAsync

Contacts.Iterate

Stream the address book one contact at a time

Alcancescontacts:readRecorre los resultados por páginas
Firma
Iterate(ctx context.Context, opts ...openemail.RequestOption) *openemail.Iterator

Returns an iterator that yields contacts individually, most recently seen first, and requests the next page only once the current one is drained. Nothing is fetched until you consume it, and breaking out of the loop stops the requests.

Parámetros

openemail.WithSourcestring

manual, auto or form. Leave it out for the whole book.

openemail.WithQstring

Searches the name and the address, up to 200 characters. When nothing matches exactly on the first page, close spellings are returned instead, and the pages that follow keep matching the same way.

openemail.WithLimitint

Page size per request, from 1 to 200, defaulting to 50 on the server.

openemail.WithCursorstring

A cursor from an earlier page to start after.

openemail.WithAPIKeystring

Overrides the client's API key for every page of this walk.

Devuelve

An *openemail.Iterator yielding one contact per step.

Ejemplo

for contact, err := range client.Contacts.Iterate(ctx, openemail.WithSource("auto")).All() {	if err != nil {		return err	} 	fmt.Println(contact.String("lastSeenAt"), contact.String("email"))}

Notas

  • The iterator is lazy, so an abandoned loop costs only the pages you consumed.

También disponible en

API
GET /contacts
TypeScript
contacts.iterate()
Python
contacts.iterate()
Ruby
contacts.iterate
PHP
contacts->iterate
Java
contacts().iterate
C#
Contacts.IterateAsync

Contacts.Get

Read one contact by email address

Alcancescontacts:read
Firma
Get(ctx context.Context, email string, opts ...openemail.RequestOption) (openemail.Object, error)

Looks up a contact by address in the workspace address book. The address is trimmed and lower cased before the lookup, so [email protected] finds [email protected], and the SDK URL encodes it for the path.

A 404 means only that the address is not in the book. It says nothing about whether mail has been exchanged with it, since received mail never creates contacts.

Parámetros

emailstringObligatorio

The contact's address, matched case insensitively.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with email, name, source, notes, photoUrl and lastSeenAt, plus audiences, every audience the contact is in as a map with id, name and builtin. builtin is default on the audience every contact belongs to and null on one somebody created. A key that also holds forms:read gets signUps, what this address sent through sign-up forms, newest first and at most 20. Each is a map with id, formId, formName, status (pending or added), answers, sourceUrl, createdAt and confirmedAt.

Ejemplo

contact, err := client.Contacts.Get(ctx, "[email protected]")if err != nil {	return err} fmt.Println(contact.String("name"), contact.String("notes"))

Notas

  • name is null for an address recorded automatically without a display name, and notes is free text somebody set in the app or through Update.

  • The address is the contact's identity here and on every other contacts route. There is no id in the public contract.

También disponible en

API
GET /contacts/{email}
TypeScript
contacts.get()
Python
contacts.get()
Ruby
contacts.get
PHP
contacts->get
Java
contacts().get
C#
Contacts.GetAsync
CLI
openemail contacts get

Contacts.Create

Save a contact in the workspace address book

Alcancescontacts:write
Firma
Create(ctx context.Context, body openemail.Body, opts ...openemail.RequestOption) (openemail.Object, error)

Adds one address to the workspace address book and returns the saved row. email is trimmed and lower cased before it is stored, so [email protected] and [email protected] are the same contact.

The contact is saved with source set to manual, the same value a contact typed into the app carries, and it joins the default audience as it is written. Every contact is in that audience for as long as it exists, so there is nothing to add afterwards. Name audiences of your own in audienceIds to put it in them in the same call, or add it later with Audiences.AddContact. Sending audienceIds also requires the audiences:write scope, since it writes memberships as well as a contact.

An address can be in the book once. A second create for an address that is already there is refused with 409 contact_exists rather than merged, so a retry cannot quietly overwrite a name somebody edited in the app. Read the existing row with Get and change it with Update.

Parámetros

emailstringObligatorio

The address to save, trimmed and lower cased before it is stored.

namestring | nil

Display name. Leave it out to save the contact without one.

notesstring | nil

Free text kept with the contact and shown beside it in the app.

audienceIds[]string

Up to 25 audience ids to put the new contact in. The default audience is joined whether or not it is named. When this is present the key also needs audiences:write, or the call is refused with 403 before anything is saved.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with email, name, source as manual, notes and lastSeenAt, which is null until mail goes to the address from the app composer, plus audiences, every audience the contact is now in, the default one included.

Ejemplo

contact, err := client.Contacts.Create(ctx, openemail.Body{	"email": "[email protected]",	"name":  "Grace Hopper",	"notes": "Met at the compiler workshop",})if err != nil {	return err} fmt.Println(contact.String("email"), contact.String("source"))

Notas

  • The SDK does not retry a create after a network failure. If you retry by hand after a lost response, a 409 contact_exists means the first attempt landed.

  • Contacts belong to the workspace, so the contact this creates is the one every member and every other key sees.

  • An id in audienceIds that is not an audience of this workspace fails the whole create. Nothing is saved.

También disponible en

API
POST /contacts
TypeScript
contacts.create()
Python
contacts.create()
Ruby
contacts.create
PHP
contacts->create
Java
contacts().create
C#
Contacts.CreateAsync
CLI
openemail contacts create

Contacts.Update

Change a contact's name or notes

Alcancescontacts:write
Firma
Update(ctx context.Context, email string, patch openemail.Body, opts ...openemail.RequestOption) (openemail.Object, error)

Changes the fields you send and leaves the rest alone. A key you leave out keeps its stored value, and an explicit null clears it, so a map with notes set to null empties the notes while an empty map changes nothing.

The address cannot be changed. It is the contact's identity, its path segment and the unique key of the book, so moving a contact to a new address is a Delete and a Create, and that new contact starts with no audience membership beyond the default one.

source and lastSeenAt are the server's to set and are not accepted here. A contact recorded automatically stays auto after you give it a name.

Parámetros

emailstringObligatorio

The contact's address, matched case insensitively.

namestring | nil

New display name. Null clears it.

notesstring | nil

New notes. Null clears them.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object as it stands after the change, with audiences alongside it.

Ejemplo

contact, err := client.Contacts.Update(ctx, "[email protected]", openemail.Body{"name": "Grace Hopper", "notes": nil})if err != nil {	return err} fmt.Println(contact.String("name"), contact.String("notes"))

Notas

  • The SDK retries this call after a network failure, since the same patch sent twice leaves the same contact.

  • An address that is not in the book is a 404, the same as Get.

  • Audience membership is not touched here. Use SetAudiences to set the whole list, or Audiences.AddContact and Audiences.RemoveContact for one audience.

También disponible en

API
PATCH /contacts/{email}
TypeScript
contacts.update()
Python
contacts.update()
Ruby
contacts.update
PHP
contacts->update
Java
contacts().update
C#
Contacts.UpdateAsync
CLI
openemail contacts update

Contacts.Delete

Delete somebody from the contacts and hide the address

Alcancescontacts:write
Firma
Delete(ctx context.Context, email string, opts ...openemail.RequestOption) (openemail.Object, error)

Does what Delete does on the Contacts page in the app. A saved contact goes with its notes, its photo and every audience it was in, the default one included. The address is then hidden: ListPeople leaves it out, and mail sent to it from the app composer no longer records it as a contact. The address can be one that was only ever seen in mail, which is how you take somebody off the people list, and wasSaved says which it was.

Nothing else moves: the mail exchanged with the address stays in the mailbox, and the address can still be written to. There is no undo. Create or Save afterwards brings the address back as a new contact with no name, no notes and no membership beyond the default audience.

Parámetros

emailstringObligatorio

The contact's address, matched case insensitively.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with object set to contact, email, deleted set to true and wasSaved.

Ejemplo

removed, err := client.Contacts.Delete(ctx, "[email protected]")if err != nil {	return err} fmt.Println(removed.String("email"), removed.Bool("deleted"))

Notas

  • An address that is not in the book is no longer a 404: it is hidden and answers with wasSaved false. Something that is not an address is a 422 invalid_contact.

  • The SDK does not retry a delete, though a second attempt is harmless: it answers with wasSaved false.

  • DeleteMany deletes up to 200 addresses in one call.

También disponible en

API
DELETE /contacts/{email}
TypeScript
contacts.delete()
Python
contacts.delete()
Ruby
contacts.delete
PHP
contacts->delete
Java
contacts().delete
C#
Contacts.DeleteAsync
CLI
openemail contacts delete

Contacts.SetAudiences

Set exactly which audiences a contact is in

Alcancesaudiences:write
Firma
SetAudiences(ctx context.Context, email string, body openemail.Body, opts ...openemail.RequestOption) (openemail.Object, error)

Makes the contact's audiences match the list you send, the way the audience picker on a contact does in the app. The contact joins every listed audience it is not in yet and leaves every other one, in one transaction, and memberships it keeps keep their addedAt.

The default audience is always kept, whether or not you name it, so an empty audienceIds list leaves the contact in the default audience alone. To add or remove one audience without restating the rest, use Audiences.AddContact or Audiences.RemoveContact.

The address is trimmed and lower cased, the SDK URL encodes it for the path, and it has to be a contact already: an address that is not in the book is a 404 contact_not_found on email. Create it with Create, which takes audienceIds too. An id that is not an audience of this workspace is a 404 audience_not_found on audienceIds, and nothing is changed.

Parámetros

emailstringObligatorio

The contact's address, matched case insensitively.

audienceIds[]stringObligatorio

Every audience the contact should be in, up to 100 ids. A repeated id counts once. More than 100 is a 422 invalid_parameter on audienceIds, and an empty id is the same error on that entry, such as audienceIds.0.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object as it stands after the change, with audiences, every audience the contact is now in as a map with id, name and builtin, the default one included.

Ejemplo

contact, err := client.Contacts.SetAudiences(ctx, "[email protected]", openemail.Body{	"audienceIds": []string{"aud_9f2c4b7e1a0d63d84c5f2e7b", "aud_1c4e7a9b2d0f36e85a7c1b4d"},})if err != nil {	return err} fmt.Println(contact.String("name"), contact.String("email"))

Notas

  • audiences:write is the only scope checked, because this writes memberships rather than the contact.

  • Safe to replay: sending the same list again changes nothing. The SDK retries it after a network failure.

  • Read the current list with Get first when you mean to add one audience to what the contact already has, or use Audiences.AddContact.

También disponible en

API
PUT /contacts/{email}/audiences
TypeScript
contacts.setAudiences()
Python
contacts.set_audiences()
Ruby
contacts.set_audiences
PHP
contacts->setAudiences
Java
contacts().setAudiences
C#
Contacts.SetAudiencesAsync
CLI
openemail contacts set-audiences

Contacts.ListPeople

List everyone on the Contacts page, saved or seen in mail

Alcancescontacts:readRecorre los resultados por páginas
Firma
ListPeople(ctx context.Context, opts ...openemail.RequestOption) (*openemail.PeoplePage, error)

Returns one page of the people the Contacts page in the app lists: the saved contacts, and every address seen in mail as the sender or a recipient of a thread's newest message. Each row says whether it is saved, how many threads it shares with the mailbox and when mail last moved (lastAt). A person seen in mail and saved is one row. List is the saved contacts alone.

The addresses seen in mail are included only when the key also holds threads:read, because they are read out of the mail. Without it the page holds the saved contacts and Seen is false. Deleted addresses and the mailbox's own addresses are never listed.

sort is recent, newest mail first and saved contacts never seen in mail after them, name, by name or else by address, ignoring case, or threads, most threads first. blockedBy on each row names the workspace blocklist rule that blocks it, and blocked: true narrows the page to those rows.

Paging is keyset. openemail.WithLimit takes 1 to 100 and defaults to 25, and NextCursor goes back as openemail.WithCursor, with the same sort, q and blocked, while HasMore is true.

Parámetros

openemail.WithQstring

Searches names, addresses and notes, up to 200 characters. When nothing matches exactly on the first page, close spellings are returned instead.

openemail.WithEmailstring

One address only, matched case insensitively: the way to read one person's thread count and last mail.

openemail.WithSortstring

recent (the default), name or threads.

openemail.WithBlockedbool

true for only the people the workspace blocklist blocks, whole-domain rules included.

openemail.WithLimitint

Rows per page, 1 to 100. The server defaults to 25.

openemail.WithCursorstring

The NextCursor from the previous page. Never build one yourself.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An *openemail.PeoplePage with Items, HasMore, NextCursor and Seen. Each person has email, displayEmail, name, saved, source, notes, photoUrl, threads, lastAt, createdAt, updatedAt and blockedBy.

Ejemplo

page, err := client.Contacts.ListPeople(ctx, openemail.WithSort("threads"), openemail.WithLimit(50))if err != nil {	return err} for _, item := range page.Items {	fmt.Println(item.String("name"), item.String("email"), item.Int("threads"), item.Bool("saved"))} fmt.Println(page.Seen, page.HasMore, page.NextCursor)

Notas

  • email is lower cased and is what every other contacts method takes. displayEmail keeps the capitals the newest message wrote.

  • A malformed or stale cursor is a 400 invalid_cursor. Start again without one.

  • A key limited to particular addresses or domains gets the saved contacts alone, with seen false, even when it holds threads:read, because the addresses seen in mail would be read from the mail of every address in the workspace.

También disponible en

API
GET /contacts/people
TypeScript
contacts.listPeople()
Python
contacts.list_people()
Ruby
contacts.list_people
PHP
contacts->listPeople
Java
contacts().listPeople
C#
Contacts.ListPeopleAsync
CLI
openemail contacts list-people

Contacts.ListAllPeople

Collect everyone on the Contacts page into one slice

Alcancescontacts:readRecorre los resultados por páginas
Firma
ListAllPeople(ctx context.Context, opts ...openemail.RequestOption) ([]openemail.Object, error)

Follows NextCursor from page to page and returns with every person ListPeople would list, in the same order and with the same filters. It is how you count the people a blocklist blocks: the length of what client.Contacts.ListAllPeople(ctx, openemail.WithBlocked(true)) returns.

Everything is held in memory before the call returns, and a busy mailbox has seen a great many addresses. Prefer IteratePeople when you can stop early.

Parámetros

openemail.WithQstring

Searches names, addresses and notes, up to 200 characters. When nothing matches exactly on the first page, close spellings are returned instead.

openemail.WithEmailstring

One address only, matched case insensitively: the way to read one person's thread count and last mail.

openemail.WithSortstring

recent (the default), name or threads.

openemail.WithBlockedbool

true for only the people the workspace blocklist blocks, whole-domain rules included.

openemail.WithLimitint

Page size per request, from 1 to 100, defaulting to 25 on the server.

openemail.WithCursorstring

A cursor from an earlier page to start after.

openemail.WithAPIKeystring

Overrides the client's API key for every page of this walk.

Devuelve

A []openemail.Object holding every person across all pages.

Ejemplo

blocked, err := client.Contacts.ListAllPeople(ctx, openemail.WithBlocked(true), openemail.WithLimit(100))if err != nil {	return err} for _, person := range blocked {	fmt.Println(person.String("name"), person.String("email"))}

Notas

  • A failure on any page fails the whole call, and the people already fetched are discarded.

  • seen is not reported here. Read one page with ListPeople to learn whether the key reads the people seen in mail.

También disponible en

API
GET /contacts/people
TypeScript
contacts.listAllPeople()
Python
contacts.list_all_people()
Ruby
contacts.list_all_people
PHP
contacts->listAllPeople
Java
contacts().listAllPeople
C#
Contacts.ListAllPeopleAsync

Contacts.IteratePeople

Stream everyone on the Contacts page one person at a time

Alcancescontacts:readRecorre los resultados por páginas
Firma
IteratePeople(ctx context.Context, opts ...openemail.RequestOption) *openemail.Iterator

Returns an iterator that yields the people ListPeople lists, one at a time, and requests the next page only once the current one is drained. Nothing is fetched until you consume it, and breaking out of the loop stops the requests.

Parámetros

openemail.WithQstring

Searches names, addresses and notes, up to 200 characters. When nothing matches exactly on the first page, close spellings are returned instead.

openemail.WithEmailstring

One address only, matched case insensitively: the way to read one person's thread count and last mail.

openemail.WithSortstring

recent (the default), name or threads.

openemail.WithBlockedbool

true for only the people the workspace blocklist blocks, whole-domain rules included.

openemail.WithLimitint

Page size per request, from 1 to 100, defaulting to 25 on the server.

openemail.WithCursorstring

A cursor from an earlier page to start after.

openemail.WithAPIKeystring

Overrides the client's API key for every page of this walk.

Devuelve

An *openemail.Iterator yielding one person per step.

Ejemplo

for person, err := range client.Contacts.IteratePeople(ctx, openemail.WithSort("recent")).All() {	if err != nil {		return err	} 	fmt.Println(person.Bool("saved"), person.Int("threads"), person.String("email"))}

Notas

  • The iterator is lazy, so an abandoned loop costs only the pages you consumed.

También disponible en

API
GET /contacts/people
TypeScript
contacts.iteratePeople()
Python
contacts.iterate_people()
Ruby
contacts.iterate_people
PHP
contacts->iteratePeople
Java
contacts().iteratePeople
C#
Contacts.IteratePeopleAsync

Contacts.Save

Save an address as a contact, or keep one that was recorded

Alcancescontacts:write
Firma
Save(ctx context.Context, email string, body openemail.Body, opts ...openemail.RequestOption) (openemail.Object, error)

Does what Add to contacts and Keep in contacts do in the app, and is safe to call whatever state the address is in. An address that is not a contact yet becomes one with source manual. A contact recorded from a send becomes manual. A contact already saved keeps what it has. A deleted address is brought back.

body.name replaces the stored name and leaving it out keeps it. body.notes replaces the stored notes and null clears them. Unlike Create, an address already in the book is not an error, and unlike Update, an address not in the book is not one either.

Parámetros

emailstringObligatorio

The address, trimmed and lower cased on the server.

namestring

Up to 200 characters. Left out, the stored name is kept.

notesstring | nil

Up to 5,000 characters. null clears the notes; left out, they are kept.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object, the contact as it stands after the save, with audiences.

Ejemplo

contact, err := client.Contacts.Save(ctx, "[email protected]", openemail.Body{"name": "Grace Hopper"})if err != nil {	return err} fmt.Println(contact.String("source"))

Notas

  • The server answers 201 for a new contact and 200 for one that was there. The call returns the same way for both, so compare createdAt with updatedAt if you need to tell them apart.

  • Safe to replay, so the SDK retries it after a network failure.

  • A new contact joins the default audience, as it does from Create.

También disponible en

API
PUT /contacts/{email}
TypeScript
contacts.save()
Python
contacts.save()
Ruby
contacts.save
PHP
contacts->save
Java
contacts().save
C#
Contacts.SaveAsync
CLI
openemail contacts save

Contacts.DeleteMany

Delete up to 200 contacts in one call

Alcancescontacts:write
Firma
DeleteMany(ctx context.Context, emails []string, opts ...openemail.RequestOption) (openemail.Object, error)

Deletes every address in emails the way Delete deletes one: a saved contact goes with its notes, its photo and every audience membership, and every address is hidden, so mail sent to it from the app composer does not record it again. Addresses that were only seen in mail are hidden too.

An entry that is not an address comes back in invalid and the rest still go through. A repeated address counts once. There is no undo.

Parámetros

emails[]stringObligatorio

1 to 200 addresses, matched case insensitively. More than 200, or none, is a 422 on emails.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with object set to contact_batch_delete, deleted, saved and invalid. deleted counts the addresses deleted and hidden, saved how many of them were saved contacts.

Ejemplo

result, err := client.Contacts.DeleteMany(ctx, []string{"[email protected]", "[email protected]"})if err != nil {	return err} fmt.Println(result.Int("deleted"), result.Int("saved"))

Notas

  • Safe to replay: deleting an address twice leaves it deleted and hidden, so the SDK retries it after a network failure.

  • No mail is deleted, and nobody is unsubscribed from anything.

También disponible en

API
POST /contacts/batch-delete
TypeScript
contacts.deleteMany()
Python
contacts.delete_many()
Ruby
contacts.delete_many
PHP
contacts->deleteMany
Java
contacts().deleteMany
C#
Contacts.DeleteManyAsync
CLI
openemail contacts delete-many

Contacts.SetPhoto

Upload the photo shown for a contact

Alcancescontacts:write
Firma
SetPhoto(ctx context.Context, email string, data io.Reader, opts ...openemail.RequestOption) (openemail.Object, error)

Sends the image bytes as the request body, replacing any photo the contact had. PNG, JPEG, WebP and GIF are accepted, up to 5 MB. The server fits the image into a 512 pixel square, stores it as WebP, keeps the first frame of an animation, and answers with the contact and its new photoUrl.

data is an io.Reader. The type is read from openemail.WithContentType. Without either the bytes go as application/octet-stream and the server refuses them with 422 invalid_image.

The address has to be a saved contact already: Save it first.

Parámetros

emailstringObligatorio

The contact's address, matched case insensitively.

dataio.ReaderObligatorio

The image, as an io.Reader.

openemail.WithContentTypestring

image/png, image/jpeg, image/webp or image/gif. The server needs it to accept the image.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with the new photoUrl.

Ejemplo

source, err := os.Open("photo.jpg")if err != nil {	return err} defer source.Close() contact, err := client.Contacts.SetPhoto(ctx, "[email protected]", source, openemail.WithContentType("image/jpeg"))if err != nil {	return err} fmt.Println(contact.String("photoUrl"))

Notas

  • An address that is not a saved contact is a 404 contact_not_found.

  • A busy image service answers 503 image_busy, which the SDK retries like any other 503.

  • Every upload gets a new URL, so a cached old photo never shows under the new one.

También disponible en

API
PUT /contacts/{email}/photo
TypeScript
contacts.setPhoto()
Python
contacts.set_photo()
Ruby
contacts.set_photo
PHP
contacts->setPhoto
Java
contacts().setPhoto
C#
Contacts.SetPhotoAsync
CLI
openemail contacts set-photo

Contacts.RemovePhoto

Remove a contact photo

Alcancescontacts:write
Firma
RemovePhoto(ctx context.Context, email string, opts ...openemail.RequestOption) (openemail.Object, error)

Takes the photo off the contact and deletes the stored image, the way Remove does on a contact in the app. The contact answers with photoUrl null. Removing a photo from a contact that has none changes nothing.

Parámetros

emailstringObligatorio

The contact's address, matched case insensitively.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with photoUrl null.

Ejemplo

contact, err := client.Contacts.RemovePhoto(ctx, "[email protected]")if err != nil {	return err} fmt.Println(contact.String("name"), contact.String("email"))

Notas

  • An address that is not a saved contact is a 404 contact_not_found.

  • Safe to replay, so the SDK retries it after a network failure.

También disponible en

API
DELETE /contacts/{email}/photo
TypeScript
contacts.removePhoto()
Python
contacts.remove_photo()
Ruby
contacts.remove_photo
PHP
contacts->removePhoto
Java
contacts().removePhoto
C#
Contacts.RemovePhotoAsync
CLI
openemail contacts remove-photo

Contacts.Block

Block an address

Alcancessettings:write
Firma
Block(ctx context.Context, email string, opts ...openemail.RequestOption) (openemail.Object, error)

Puts the address on the workspace blocklist, the same list Settings.Update edits as blockedSenders, so mail from it is refused from then on. This is Block on a contact in the app. A plus tag is dropped: blocking [email protected] blocks [email protected], and every tag of it.

When a rule already blocks the address, a whole-domain rule included, nothing is added: created is false and blockedBy names that rule. The address does not have to be a contact.

Parámetros

emailstringObligatorio

The address to block.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with object set to contact_block, email, blocked set to true, blockedBy and created.

Ejemplo

result, err := client.Contacts.Block(ctx, "[email protected]")if err != nil {	return err} fmt.Println(result.Bool("created"), result.Object("blockedBy").String("rule"))

Notas

  • It needs settings:write rather than contacts:write, because it writes the blocklist rather than the contact.

  • Safe to replay, so the SDK retries it after a network failure.

  • An address with fewer than two letters or numbers is refused with 422 blocklist_entry_too_broad.

  • A key limited to particular addresses or domains gets 422 capability_unsupported on addressAllowlist, because the blocklist belongs to the whole workspace and filters the mail of every address in it.

También disponible en

API
POST /contacts/{email}/block
TypeScript
contacts.block()
Python
contacts.block()
Ruby
contacts.block
PHP
contacts->block
Java
contacts().block
C#
Contacts.BlockAsync
CLI
openemail contacts block

Contacts.Unblock

Unblock an address

Alcancessettings:write
Firma
Unblock(ctx context.Context, email string, opts ...openemail.RequestOption) (openemail.Object, error)

Takes every workspace blocklist rule that blocks the address off the list and lists them in removed. This is Unblock on a contact in the app.

When one of them is a whole-domain rule, in blockedDomains, everybody at that domain is unblocked with it, so check removed when that matters. Rules set for one address or one domain in the settings are not touched. An address that no rule blocks answers with removed empty.

Parámetros

emailstringObligatorio

The address to unblock.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with object set to contact_block, email, blocked set to false and removed, each entry of removed a a map with rule and list.

Ejemplo

result, err := client.Contacts.Unblock(ctx, "[email protected]")if err != nil {	return err} fmt.Println(result.String("email"), result.String("object"))

Notas

  • Safe to replay, so the SDK retries it after a network failure.

  • A key limited to particular addresses or domains gets 422 capability_unsupported on addressAllowlist, because the blocklist belongs to the whole workspace and filters the mail of every address in it.

También disponible en

API
DELETE /contacts/{email}/block
TypeScript
contacts.unblock()
Python
contacts.unblock()
Ruby
contacts.unblock
PHP
contacts->unblock
Java
contacts().unblock
C#
Contacts.UnblockAsync
CLI
openemail contacts unblock

Contacts.ListThreads

List the conversations with one person

Alcancesthreads:readRecorre los resultados por páginas
Firma
ListThreads(ctx context.Context, email string, opts ...openemail.RequestOption) (*openemail.Page, error)

Returns one page of the threads the address wrote or was written to, in every folder: the Mail tab on a contact in the app. Each row is a summary, subject, from, receivedAt, messageCount, hasUnread and labels, and Threads.Get reads the messages behind its id.

openemail.WithLimit takes 1 to 100 and defaults to 25. Pass NextCursor back as openemail.WithCursor, with the same q and sort, while HasMore is true.

Parámetros

emailstringObligatorio

The address. It does not have to be a saved contact.

openemail.WithQstring

Searches inside those threads, with the mailbox search syntax, up to 200 characters.

openemail.WithSortstring

newest (the default), oldest, sender or subject.

openemail.WithLimitint

Threads per page, 1 to 100. The server defaults to 25.

openemail.WithCursorstring

The NextCursor from the previous page. Never build one yourself.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

A *openemail.Page with Items, HasMore and NextCursor.

Ejemplo

page, err := client.Contacts.ListThreads(ctx, "[email protected]", openemail.WithQ("invoice"))if err != nil {	return err} for _, thread := range page.Items {	fmt.Println(thread.String("receivedAt"), thread.String("subject"))} fmt.Println(page.HasMore, page.NextCursor)

Notas

  • It needs threads:read, because it reads mail rather than the contact.

  • A key limited to particular addresses or domains gets 422 capability_unsupported on addressAllowlist, because a contact's threads and activity are read from the mail of every address in the workspace.

También disponible en

API
GET /contacts/{email}/threads
TypeScript
contacts.listThreads()
Python
contacts.list_threads()
Ruby
contacts.list_threads
PHP
contacts->listThreads
Java
contacts().listThreads
C#
Contacts.ListThreadsAsync
CLI
openemail contacts list-threads

Contacts.ListAllThreads

Collect every conversation with one person into one slice

Alcancesthreads:readRecorre los resultados por páginas
Firma
ListAllThreads(ctx context.Context, email string, opts ...openemail.RequestOption) ([]openemail.Object, error)

Follows NextCursor from page to page and returns with every thread ListThreads would list for the address, in the same order.

Everything is held in memory before the call returns. Prefer IterateThreads when you can stop early.

Parámetros

emailstringObligatorio

The address. It does not have to be a saved contact.

openemail.WithQstring

Searches inside those threads, with the mailbox search syntax, up to 200 characters.

openemail.WithSortstring

newest (the default), oldest, sender or subject.

openemail.WithLimitint

Page size per request, from 1 to 100, defaulting to 25 on the server.

openemail.WithCursorstring

A cursor from an earlier page to start after.

openemail.WithAPIKeystring

Overrides the client's API key for every page of this walk.

Devuelve

A []openemail.Object holding every thread across all pages.

Ejemplo

threads, err := client.Contacts.ListAllThreads(ctx, "[email protected]")if err != nil {	return err} for _, thread := range threads {	fmt.Println(thread.String("id"), thread.String("subject"))}

Notas

  • A failure on any page fails the whole call, and the threads already fetched are discarded.

También disponible en

API
GET /contacts/{email}/threads
TypeScript
contacts.listAllThreads()
Python
contacts.list_all_threads()
Ruby
contacts.list_all_threads
PHP
contacts->listAllThreads
Java
contacts().listAllThreads
C#
Contacts.ListAllThreadsAsync

Contacts.IterateThreads

Stream the conversations with one person one thread at a time

Alcancesthreads:readRecorre los resultados por páginas
Firma
IterateThreads(ctx context.Context, email string, opts ...openemail.RequestOption) *openemail.Iterator

Returns an iterator that yields the threads ListThreads lists for the address, one at a time, and requests the next page only once the current one is drained. Nothing is fetched until you consume it, and breaking out of the loop stops the requests.

Parámetros

emailstringObligatorio

The address. It does not have to be a saved contact.

openemail.WithQstring

Searches inside those threads, with the mailbox search syntax, up to 200 characters.

openemail.WithSortstring

newest (the default), oldest, sender or subject.

openemail.WithLimitint

Page size per request, from 1 to 100, defaulting to 25 on the server.

openemail.WithCursorstring

A cursor from an earlier page to start after.

openemail.WithAPIKeystring

Overrides the client's API key for every page of this walk.

Devuelve

An *openemail.Iterator yielding one thread per step.

Ejemplo

for thread, err := range client.Contacts.IterateThreads(ctx, "[email protected]").All() {	if err != nil {		return err	} 	fmt.Println(thread.Bool("hasUnread"), thread.String("subject"))}

Notas

  • The iterator is lazy, so an abandoned loop costs only the pages you consumed.

También disponible en

API
GET /contacts/{email}/threads
TypeScript
contacts.iterateThreads()
Python
contacts.iterate_threads()
Ruby
contacts.iterate_threads
PHP
contacts->iterateThreads
Java
contacts().iterateThreads
C#
Contacts.IterateThreadsAsync

Contacts.Activity

Read how mail with one person has gone over a window

Alcancesthreads:read
Firma
Activity(ctx context.Context, email string, opts ...openemail.RequestOption) (openemail.Object, error)

Returns the numbers behind the Activity tab on a contact in the app, over a window that ends now: messages received from the address and sent to it per bucket, the threads that moved, the threads whose newest message is theirs and so waits on a reply from the mailbox, when each side last wrote, and the median time each side takes to answer, in milliseconds.

openemail.WithMinutes sets how far back the window reaches, 90 days by default. grain sets the bucket width and the key shape, YYYY-MM-DD, YYYY-MM-DDTHH or YYYY-MM-DDTHH:MM, and offsetMinutes shifts the boundaries so days break where the reader's day does. buckets is sparse and oldest first. Mail in the bin or in spam is left out.

Parámetros

emailstringObligatorio

The address. It does not have to be a saved contact.

openemail.WithMinutesint

Window length in minutes, from 1 to about 20 years. The server defaults to 90 days.

openemail.WithGrainstring

Bucket width: minute, hour or day, defaulting to day.

openemail.WithOffsetMinutesint

Minutes east of UTC to cut the buckets in, from -840 to 840, defaulting to 0. For the local zone, pass the offset time.Now().Zone() reports, divided by 60.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with object set to contact_activity, email, since, until, grain, buckets, totals and replyTime. totals has received, sent, threads, waiting, lastReceivedAt and lastSentAt; replyTime has yours and theirs, each null when there is no reply to measure.

Ejemplo

activity, err := client.Contacts.Activity(ctx, "[email protected]", openemail.WithMinutes(30*24*60))if err != nil {	return err} totals := activity.Object("totals") fmt.Println(totals.Int("received"), "in,", totals.Int("sent"), "out,", totals.Int("waiting"), "waiting on you")

Notas

  • It needs threads:read, because it reads mail rather than the contact.

  • Read only, so the SDK retries it after a network failure like any other read.

  • A key limited to particular addresses or domains gets 422 capability_unsupported on addressAllowlist, because a contact's threads and activity are read from the mail of every address in the workspace.

También disponible en

API
GET /contacts/{email}/activity
TypeScript
contacts.activity()
Python
contacts.activity()
Ruby
contacts.activity
PHP
contacts->activity
Java
contacts().activity
C#
Contacts.ActivityAsync
CLI
openemail contacts activity

Contacts.ListEvents

List the events recorded for one contact

Alcancescontacts:readRecorre los resultados por páginas
Firma
ListEvents(ctx context.Context, email string, opts ...openemail.RequestOption) (*openemail.Page, error)

Returns one page of the events Events.Send recorded for a contact in the last 90 days, the most recent first by when they happened. Each has its name, properties, occurredAt and mode, which is test for an event a test key sent.

openemail.WithLimit takes 1 to 200 and defaults to 50. Pass NextCursor back as openemail.WithCursor, with the same openemail.WithName, while HasMore is true. ListAllEvents and IterateEvents do that walk for you.

Parámetros

emailstringObligatorio

The contact, by email address, compared without case. The contactId an event or an enrollment carries works here too.

openemail.WithNamestring

Only events with exactly this name.

openemail.WithLimitint

Events per page, a whole number from 1 to 200. The server defaults to 50.

openemail.WithCursorstring

The NextCursor from the previous page, passed back exactly as it came. One that names no event of this contact is a 400 invalid_cursor.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

A *openemail.Page with Items, HasMore and NextCursor. Each item has id, contactId, email, name, properties, occurredAt, mode and createdAt.

Ejemplo

page, err := client.Contacts.ListEvents(ctx, "[email protected]", openemail.WithName("order.placed"))if err != nil {	return err} for _, event := range page.Items {	fmt.Println(event.String("occurredAt"), event.String("name"), event.Object("properties"))} fmt.Println(page.HasMore, page.NextCursor)

Notas

  • An address or id nobody you can reach has is 404 contact_not_found. An app a member connected reads only the contacts that member added.

  • Read only, so the SDK retries it after a network failure like any other read.

También disponible en

API
GET /contacts/{email}/events
TypeScript
contacts.listEvents()
Python
contacts.list_events()
Ruby
contacts.list_events
PHP
contacts->listEvents
Java
contacts().listEvents
C#
Contacts.ListEventsAsync
CLI
openemail contacts list-events

Contacts.ListAllEvents

Collect every event of one contact into one slice

Alcancescontacts:readRecorre los resultados por páginas
Firma
ListAllEvents(ctx context.Context, email string, opts ...openemail.RequestOption) ([]openemail.Object, error)

Follows NextCursor from page to page and returns with every event recorded for the contact in the last 90 days, the most recent first, in the shape ListEvents returns. openemail.WithLimit sets the page size of each request, not the total.

Parámetros

emailstringObligatorio

The contact, by email address, compared without case. The contactId an event or an enrollment carries works here too.

openemail.WithNamestring

Only events with exactly this name.

openemail.WithLimitint

Page size per request, from 1 to 200, defaulting to 50 on the server.

openemail.WithCursorstring

A NextCursor from an earlier page to start after.

openemail.WithAPIKeystring

Overrides the client's API key for every page of this walk.

Devuelve

A []openemail.Object holding every matching event across all pages.

Ejemplo

events, err := client.Contacts.ListAllEvents(ctx, "[email protected]")if err != nil {	return err} names := map[string]bool{} for _, event := range events {	names[event.String("name")] = true} fmt.Println(len(events), "events under", len(names), "names")

Notas

  • A failure on any page fails the whole call.

También disponible en

API
GET /contacts/{email}/events
TypeScript
contacts.listAllEvents()
Python
contacts.list_all_events()
Ruby
contacts.list_all_events
PHP
contacts->listAllEvents
Java
contacts().listAllEvents
C#
Contacts.ListAllEventsAsync

Contacts.IterateEvents

Stream the events of one contact one at a time

Alcancescontacts:readRecorre los resultados por páginas
Firma
IterateEvents(ctx context.Context, email string, opts ...openemail.RequestOption) *openemail.Iterator

Returns an iterator that yields the events of a contact one by one, the most recent first, and requests the next page only once the current one is drained. Breaking out of the loop stops the requests.

Parámetros

emailstringObligatorio

The contact, by email address, compared without case. The contactId an event or an enrollment carries works here too.

openemail.WithNamestring

Only events with exactly this name.

openemail.WithLimitint

Page size per request, from 1 to 200, defaulting to 50 on the server.

openemail.WithCursorstring

A NextCursor from an earlier page to start after.

openemail.WithAPIKeystring

Overrides the client's API key for every page of this walk.

Devuelve

An *openemail.Iterator yielding one event per step.

Ejemplo

for event, err := range client.Contacts.IterateEvents(ctx, "[email protected]").All() {	if err != nil {		return err	} 	if event.String("name") == "plan.cancelled" {		fmt.Println("cancelled on", event.String("occurredAt")) 		break	}}

Notas

  • The iterator is lazy, so an abandoned loop costs only the pages you consumed.

También disponible en

API
GET /contacts/{email}/events
TypeScript
contacts.iterateEvents()
Python
contacts.iterate_events()
Ruby
contacts.iterate_events
PHP
contacts->iterateEvents
Java
contacts().iterateEvents
C#
Contacts.IterateEventsAsync

Contacts.ListCards

List the address book as contact cards

Alcancescontacts:readRecorre los resultados por páginas
Firma
ListCards(ctx context.Context, opts ...openemail.RequestOption) (*openemail.Page, error)

Returns one page of contact cards, newest first. A card is a saved contact with everything an address book keeps for it: phone numbers, other email addresses, postal addresses, websites, organisation, job title and birthday. Cards with no email address, such as a plumber saved on a phone, are listed too. It is the address book phones and computers sync over CardDAV.

openemail.WithEmail finds the card of one saved contact, and openemail.WithWithoutEmail lists only the cards with no address. An address that was only ever mailed, and never saved, has no card.

Paging is keyset. openemail.WithLimit takes 1 to 200 and defaults to 50, and NextCursor goes back as openemail.WithCursor while HasMore is true.

Parámetros

openemail.WithLimitint

Cards per page, a whole number from 1 to 200. The server defaults to 50.

openemail.WithCursorstring

The NextCursor from the previous page. Never build one yourself.

openemail.WithEmailstring

Only the card of the saved contact with this address.

openemail.WithWithoutEmailbool

True lists only the cards that have no email address.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

A *openemail.Page with Items, HasMore and NextCursor.

Ejemplo

page, err := client.Contacts.ListCards(ctx, openemail.WithWithoutEmail(true))if err != nil {	return err} for _, card := range page.Items {	fmt.Println(card.String("name"))} fmt.Println(page.HasMore, page.NextCursor)

Notas

  • Every member reads the same address book through a key, since a key acts for the workspace owner.

  • A cursor that names no card is a 400 invalid_cursor.

También disponible en

API
GET /contacts/cards
TypeScript
contacts.listCards()
Python
contacts.list_cards()
Ruby
contacts.list_cards
PHP
contacts->listCards
Java
contacts().listCards
C#
Contacts.ListCardsAsync
CLI
openemail contacts list-cards

Contacts.ListAllCards

Collect every contact card into one slice

Alcancescontacts:readRecorre los resultados por páginas
Firma
ListAllCards(ctx context.Context, opts ...openemail.RequestOption) ([]openemail.Object, error)

Follows NextCursor from page to page and returns with every card in the address book, newest first. It takes the same email and withoutEmail filters as ListCards.

Everything is held in memory before the call returns. Prefer IterateCards when you can stop early. limit sets the page size of each request, not the total.

Parámetros

openemail.WithEmailstring

Only the card of the saved contact with this address.

openemail.WithWithoutEmailbool

True lists only the cards that have no email address.

openemail.WithLimitint

Page size per request, from 1 to 200, defaulting to 50 on the server.

openemail.WithCursorstring

A cursor from an earlier page to start after.

openemail.WithAPIKeystring

Overrides the client's API key for every page of this walk.

Devuelve

A []openemail.Object holding every card across all pages.

Ejemplo

cards, err := client.Contacts.ListAllCards(ctx)if err != nil {	return err} for _, card := range cards {	fmt.Println(card.String("id"), card.String("name"))}

Notas

  • A failure on any page fails the whole call, and the cards already fetched are discarded.

También disponible en

API
GET /contacts/cards
TypeScript
contacts.listAllCards()
Python
contacts.list_all_cards()
Ruby
contacts.list_all_cards
PHP
contacts->listAllCards
Java
contacts().listAllCards
C#
Contacts.ListAllCardsAsync

Contacts.IterateCards

Stream the address book one card at a time

Alcancescontacts:readRecorre los resultados por páginas
Firma
IterateCards(ctx context.Context, opts ...openemail.RequestOption) *openemail.Iterator

Returns an iterator that yields cards one by one, newest first, and requests the next page only once the current one is drained. Nothing is fetched until you consume it, and breaking out of the loop stops the requests.

Parámetros

openemail.WithEmailstring

Only the card of the saved contact with this address.

openemail.WithWithoutEmailbool

True lists only the cards that have no email address.

openemail.WithLimitint

Page size per request, from 1 to 200, defaulting to 50 on the server.

openemail.WithCursorstring

A cursor from an earlier page to start after.

openemail.WithAPIKeystring

Overrides the client's API key for every page of this walk.

Devuelve

An *openemail.Iterator yielding one card per step.

Ejemplo

for card, err := range client.Contacts.IterateCards(ctx).All() {	if err != nil {		return err	} 	fmt.Println(card.String("birthday"), card.String("name"))}

Notas

  • The iterator is lazy, so an abandoned loop costs only the pages you consumed.

También disponible en

API
GET /contacts/cards
TypeScript
contacts.iterateCards()
Python
contacts.iterate_cards()
Ruby
contacts.iterate_cards
PHP
contacts->iterateCards
Java
contacts().iterateCards
C#
Contacts.IterateCardsAsync

Contacts.GetCard

Get one contact card

Alcancescontacts:read
Firma
GetCard(ctx context.Context, id string, opts ...openemail.RequestOption) (openemail.Object, error)

Returns one card with everything it holds. To find the card of a saved contact by its address, list the cards with email.

Parámetros

idstringObligatorio

The card id, ccd_ and 24 characters, from ListCards or GetCard.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object.

Ejemplo

card, err := client.Contacts.GetCard(ctx, "ccd_0123456789abcdef01234567")if err != nil {	return err} fmt.Println(card.String("name"), card.String("organization"))

Notas

También disponible en

API
GET /contacts/cards/{id}
TypeScript
contacts.getCard()
Python
contacts.get_card()
Ruby
contacts.get_card
PHP
contacts->getCard
Java
contacts().getCard
C#
Contacts.GetCardAsync
CLI
openemail contacts get-card

Contacts.CreateCard

Add a card to the address book

Alcancescontacts:write
Firma
CreateCard(ctx context.Context, body openemail.Body, opts ...openemail.RequestOption) (openemail.Object, error)

Adds a contact card. With email the card is a saved contact as well, the same one Create makes, and an address the workspace already knows from mail becomes saved. Without one it is a card on its own, kept for its name, phone numbers and the rest. A card needs at least a name, an email address, a phone number or an organisation.

Phones and computers that sync the address book over CardDAV get the new card on their next sync.

Parámetros

emailstring | nil

The address OpenEmail knows the contact by. Given to a card that has none, it makes the card a saved contact. A saved contact keeps its address, so put any other address in emails.

namestring | nil

The full name the address book shows, up to 200 characters.

namePartsopenemail.Body | nil

The name in parts, a map with prefix, given, middle, family and suffix, the way phones keep it.

nicknamestring | nil

A nickname.

organizationstring | nil

The company or organisation.

departmentstring | nil

The department within the organisation.

titlestring | nil

The job title.

birthdaystring | nil

YYYY-MM-DD, or --MM-DD when the year is not known.

notesstring | nil

Free-form notes. On a saved contact these are the notes the contact page shows.

emails[]openemail.Body

Other email addresses besides email, each a map with value and optionally label and customLabel.

phones[]openemail.Body

Phone numbers, each a map with value and optionally label and customLabel.

addresses[]openemail.Body

Postal addresses, each a map with optionally label, customLabel, street, locality, region, postalCode and country.

urls[]openemail.Body

Websites and profile links, each a map with value and optionally label and customLabel.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object for the new card.

Ejemplo

card, err := client.Contacts.CreateCard(ctx, openemail.Body{	"email":        "[email protected]",	"name":         "Ada Lovelace",	"organization": "Analytical Engines",	"phones": []openemail.Body{		{"value": "+44 20 7946 0000", "label": "work"},	},	"birthday": "1815-12-10",})if err != nil {	return err} fmt.Println(card.String("id"), card.String("email"))

Notas

También disponible en

API
POST /contacts/cards
TypeScript
contacts.createCard()
Python
contacts.create_card()
Ruby
contacts.create_card
PHP
contacts->createCard
Java
contacts().createCard
C#
Contacts.CreateCardAsync
CLI
openemail contacts create-card

Contacts.UpdateCard

Change a contact card

Alcancescontacts:write
Firma
UpdateCard(ctx context.Context, id string, patch openemail.Body, opts ...openemail.RequestOption) (openemail.Object, error)

Changes the fields you send and leaves the rest alone. null clears a field, and a list you send (emails, phones, addresses, urls) replaces the whole list, so read the card first when you mean to add one entry.

On a saved contact, name and notes are the contact's own, so the contact page shows the change. email can only be given to a card that has none, which makes it a saved contact. A saved contact keeps its address: add another address to emails instead.

Parámetros

idstringObligatorio

The card id, ccd_ and 24 characters, from ListCards or GetCard.

emailstring | nil

The address OpenEmail knows the contact by. Given to a card that has none, it makes the card a saved contact. A saved contact keeps its address, so put any other address in emails.

namestring | nil

The full name the address book shows, up to 200 characters.

namePartsopenemail.Body | nil

The name in parts, a map with prefix, given, middle, family and suffix, the way phones keep it.

nicknamestring | nil

A nickname.

organizationstring | nil

The company or organisation.

departmentstring | nil

The department within the organisation.

titlestring | nil

The job title.

birthdaystring | nil

YYYY-MM-DD, or --MM-DD when the year is not known.

notesstring | nil

Free-form notes. On a saved contact these are the notes the contact page shows.

emails[]openemail.Body

Other email addresses besides email, each a map with value and optionally label and customLabel.

phones[]openemail.Body

Phone numbers, each a map with value and optionally label and customLabel.

addresses[]openemail.Body

Postal addresses, each a map with optionally label, customLabel, street, locality, region, postalCode and country.

urls[]openemail.Body

Websites and profile links, each a map with value and optionally label and customLabel.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object as it stands after the change.

Ejemplo

card, err := client.Contacts.GetCard(ctx, "ccd_0123456789abcdef01234567")if err != nil {	return err} phones := append(card.Objects("phones"), openemail.Object{"value": "+1 555 0100", "label": "mobile"}) updated, err := client.Contacts.UpdateCard(ctx, card.ID(), openemail.Body{"phones": phones})if err != nil {	return err} fmt.Println(len(updated.Objects("phones")))

Notas

  • The SDK retries this call after a network failure, since the same patch sent twice leaves the same card.

  • Changing the address of a saved contact is a 422 invalid_contact_card.

También disponible en

API
PATCH /contacts/cards/{id}
TypeScript
contacts.updateCard()
Python
contacts.update_card()
Ruby
contacts.update_card
PHP
contacts->updateCard
Java
contacts().updateCard
C#
Contacts.UpdateCardAsync
CLI
openemail contacts update-card

Contacts.DeleteCard

Delete a contact card

Alcancescontacts:write
Firma
DeleteCard(ctx context.Context, id string, opts ...openemail.RequestOption) (openemail.Object, error)

Removes the card from the address book and from every phone and computer that syncs it. On a saved contact it is the same as Delete: the contact goes with its notes, photo and audiences, and the address is hidden from the people list and the suggestions.

Parámetros

idstringObligatorio

The card id, ccd_ and 24 characters, from ListCards or GetCard.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with object set to contact_card, id and deleted set to true.

Ejemplo

removed, err := client.Contacts.DeleteCard(ctx, "ccd_0123456789abcdef01234567")if err != nil {	return err} fmt.Println(removed.String("id"), removed.Bool("deleted"))

Notas

  • There is no undo.

También disponible en

API
DELETE /contacts/cards/{id}
TypeScript
contacts.deleteCard()
Python
contacts.delete_card()
Ruby
contacts.delete_card
PHP
contacts->deleteCard
Java
contacts().deleteCard
C#
Contacts.DeleteCardAsync
CLI
openemail contacts delete-card

Contacts.ImportVcf

Import a contacts file

Alcancescontacts:write
Firma
ImportVcf(ctx context.Context, data io.Reader, opts ...openemail.RequestOption) (openemail.Object, error)

Sends a vCard (.vcf) file as the request body and queues it. Every card in it becomes a contact card, with its phone numbers, addresses and the rest. Poll GetImport until status is completed.

The file may be 20 MB. Imported contacts join no audience, so a broadcast never reaches them because of an import. A card whose address or UID is already in the address book is counted under merged and left as it is, and a card with no address is matched on its phone number. A workspace keeps 20,000 cards, and the cards past that are counted under skipped.

data is an io.Reader, and it goes out as text/vcard.

Parámetros

dataio.ReaderObligatorio

The .vcf file: an io.Reader.

openemail.WithFilenamestring

The name to show for the file in the list of imports, at most 255 characters.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with status: queued.

Ejemplo

source, err := os.Open("contacts.vcf")if err != nil {	return err} defer source.Close() queued, err := client.Contacts.ImportVcf(ctx, source, openemail.WithFilename("contacts.vcf"))if err != nil {	return err} fmt.Println(queued.ID(), queued.String("status"))

Notas

  • A body that holds no vCard is a 400 not_a_contacts_file, and an empty one a 400 item_import_empty.

  • A file over 20 MB is a 413 item_import_too_large.

  • To send text you already hold, wrap it in strings.NewReader(text).

  • An upload that outlasts the client timeout fails as a network error, so raise it on the client for a large file on a slow connection.

  • Not retried automatically.

También disponible en

API
POST /contacts/imports
TypeScript
contacts.importVcf()
Python
contacts.import_vcf()
Ruby
contacts.import_vcf
PHP
contacts->importVcf
Java
contacts().importVcf
C#
Contacts.ImportVcfAsync
CLI
openemail contacts import-vcf

Contacts.ListImports

List contacts imports

Alcancescontacts:readRecorre los resultados por páginas
Firma
ListImports(ctx context.Context, opts ...openemail.RequestOption) (*openemail.Page, error)

Returns one page of the contacts files and address books brought in, newest first, each with what it added and what it left out. Beside the files sent with ImportVcf it lists the address books that came with a mailbox import, and those carry the id of that import in parentImportId.

Paging is keyset. openemail.WithLimit takes 1 to 100 and defaults to 25, and NextCursor goes back as openemail.WithCursor while HasMore is true. ListAllImports and IterateImports do that walk for you.

Parámetros

openemail.WithLimitint

Imports per page, a whole number from 1 to 100. The server defaults to 25.

openemail.WithCursorstring

The NextCursor from the previous page. Never build one yourself.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

A *openemail.Page with Items, HasMore and NextCursor.

Ejemplo

page, err := client.Contacts.ListImports(ctx, openemail.WithLimit(50))if err != nil {	return err} for _, job := range page.Items {	fmt.Println(job.String("fileName"), job.String("status"), job.Object("counts").Int("imported"), job.Object("counts").Int("merged"))} fmt.Println(page.HasMore, page.NextCursor)

Notas

  • source is file for an upload. takeout, carddav and microsoft came with a mailbox import.

  • A cursor that names no import is a 400 invalid_cursor.

  • A GET is retried automatically on network failure and on 408, 500, 502, 503 and 504 responses, up to the client's openemail.WithMaxRetries, and on a 429 only when it carries a Retry-After of a minute or less.

También disponible en

API
GET /contacts/imports
TypeScript
contacts.listImports()
Python
contacts.list_imports()
Ruby
contacts.list_imports
PHP
contacts->listImports
Java
contacts().listImports
C#
Contacts.ListImportsAsync
CLI
openemail contacts list-imports

Contacts.ListAllImports

Collect every contacts import into one slice

Alcancescontacts:readRecorre los resultados por páginas
Firma
ListAllImports(ctx context.Context, opts ...openemail.RequestOption) ([]openemail.Object, error)

Follows NextCursor from page to page and returns with every contacts import, newest first.

Everything is held in memory before the call returns. Prefer IterateImports when you can stop early. limit sets the page size of each request, not the total.

Parámetros

openemail.WithLimitint

Page size per request, from 1 to 100, defaulting to 25 on the server.

openemail.WithCursorstring

A cursor from an earlier page to start after.

openemail.WithAPIKeystring

Overrides the client's API key for every page of this walk.

Devuelve

A []openemail.Object holding every import across all pages.

Ejemplo

imports, err := client.Contacts.ListAllImports(ctx)if err != nil {	return err} added := 0 for _, job := range imports {	added += job.Object("counts").Int("imported")} fmt.Println(added, "cards came from", len(imports), "imports")

Notas

  • A failure on any page fails the whole call, and the imports already fetched are discarded.

También disponible en

API
GET /contacts/imports
TypeScript
contacts.listAllImports()
Python
contacts.list_all_imports()
Ruby
contacts.list_all_imports
PHP
contacts->listAllImports
Java
contacts().listAllImports
C#
Contacts.ListAllImportsAsync

Contacts.IterateImports

Stream contacts imports one at a time

Alcancescontacts:readRecorre los resultados por páginas
Firma
IterateImports(ctx context.Context, opts ...openemail.RequestOption) *openemail.Iterator

Returns an iterator that yields contacts imports one by one, newest first, and requests the next page only once the current one is drained. Nothing is fetched until you consume it, and breaking out of the loop stops the requests.

Parámetros

openemail.WithLimitint

Page size per request, from 1 to 100, defaulting to 25 on the server.

openemail.WithCursorstring

A cursor from an earlier page to start after.

openemail.WithAPIKeystring

Overrides the client's API key for every page of this walk.

Devuelve

An *openemail.Iterator yielding one import per step.

Ejemplo

for job, err := range client.Contacts.IterateImports(ctx).All() {	if err != nil {		return err	} 	if job.String("status") != "running" {		continue	} 	fmt.Println("still running", job.ID(), job.Object("counts").Int("total")) 	break}

Notas

  • The iterator is lazy, so an abandoned loop costs only the pages you consumed.

También disponible en

API
GET /contacts/imports
TypeScript
contacts.iterateImports()
Python
contacts.iterate_imports()
Ruby
contacts.iterate_imports
PHP
contacts->iterateImports
Java
contacts().iterateImports
C#
Contacts.IterateImportsAsync

Contacts.GetImport

Get a contacts import

Alcancescontacts:read
Firma
GetImport(ctx context.Context, id string, opts ...openemail.RequestOption) (openemail.Object, error)

Returns one contacts import with its counts and its report: the files it read, how many cards it left out and why, and up to 20 of the cards it left out. Poll it after ImportVcf until status is completed or failed.

counts.imported is what was added, counts.merged the cards left as they were because they were already in the address book, and counts.skipped what was left out, which report.skipped breaks down by reason: limit for a card past the 20,000 a workspace keeps, invalid for one that could not be read and empty for one that held nothing.

Parámetros

idstringObligatorio

Contacts import id, iimp_ followed by 24 hex characters.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with status, counts, report, undoable and when it started, finished and was undone.

Ejemplo

item, err := client.Contacts.GetImport(ctx, "iimp_7b1e4d8f60a5c7b92d3f9c2a")if err != nil {	return err} counts := item.Object("counts") fmt.Println(item.String("status"), counts.Int("imported"), counts.Int("merged"), counts.Int("skipped")) for _, sample := range item.Object("report").Objects("samples") {	fmt.Println(sample.String("name"), sample.String("reason"))}

Notas

  • An id that names no contacts import is a 404 item_import_not_found.

  • A GET is retried automatically on network failure and on 408, 500, 502, 503 and 504 responses, up to the client's openemail.WithMaxRetries, and on a 429 only when it carries a Retry-After of a minute or less.

También disponible en

API
GET /contacts/imports/{id}
TypeScript
contacts.getImport()
Python
contacts.get_import()
Ruby
contacts.get_import
PHP
contacts->getImport
Java
contacts().getImport
C#
Contacts.GetImportAsync
CLI
openemail contacts get-import

Contacts.UndoImport

Remove what a contacts import added

Alcancescontacts:write
Firma
UndoImport(ctx context.Context, id string, opts ...openemail.RequestOption) (openemail.Object, error)

Deletes every contact and card the import added, changed since or not, and marks the import undone. Contacts that were already in the address book are not touched.

Parámetros

idstringObligatorio

Contacts import id, iimp_ followed by 24 hex characters.

openemail.WithAPIKeystring

Overrides the client's API key for this call only.

Devuelve

An openemail.Object with status: undone and undoneAt set.

Ejemplo

undone, err := client.Contacts.UndoImport(ctx, "iimp_7b1e4d8f60a5c7b92d3f9c2a")if err != nil {	return err} fmt.Println(undone.String("status"), undone.String("undoneAt"), undone.Object("counts").Int("imported"))

Notas

  • An import that is still running, or was already removed, is a 409 item_import_not_undoable. undoable on the import says whether the call would remove anything.

  • An id that names no contacts import is a 404 item_import_not_found.

  • Not retried automatically.

También disponible en

API
POST /contacts/imports/{id}/undo
TypeScript
contacts.undoImport()
Python
contacts.undo_import()
Ruby
contacts.undo_import
PHP
contacts->undoImport
Java
contacts().undoImport
C#
Contacts.UndoImportAsync
CLI
openemail contacts undo-import