Skip to content
Shiny.NET

Contacts

NuGet package Shiny.AppDeviceBridge.Contacts

The contacts bridge searches, reads, creates, updates and deletes the device’s contacts, backed by Shiny.Contacts.

Terminal window
dotnet add package Shiny.AppDeviceBridge.Contacts
builder.UseAppDeviceBridge(
bridge => bridge.AddContactsBridge(),
webApp => { /* … */ }
);
Client C# TypeScript
IContactsBridge AddContactsBridgeClient() ContactsBridge
Topic Details
Platforms Android and iOS. Shiny.Contacts has no Mac Catalyst, macOS, Windows or Linux backend, so there every endpoint returns 501.
Listing GET contacts/items?search=&offset=&limit= returns one page (50 by default, 500 at most) and hasMore. search matches names, phone numbers and emails.
Photos photos never go in the JSON. hasPhoto says whether one exists, and GET contacts/items/{id}/photo?size=full|thumbnail returns the image bytes.
Writing PUT changes only the properties you send. An empty list clears one.
iOS reading note and relationships needs the com.apple.developer.contacts.notes entitlement. Without it they come back empty.

Every route answers 403 access_denied until access has been granted.

import { ContactsBridge } from "@shinyorg/appdevicebridge";
const contacts = new ContactsBridge();
await contacts.requestAccess();
const page = await contacts.getContacts({ search: "smith", limit: 25 });
for (const c of page.items) console.log(c.id, c.givenName, c.familyName);
const photo = await contacts.getPhoto(page.items[0].id, { size: "Thumbnail" });
img.src = URL.createObjectURL(photo);
const { id } = await contacts.createContact({
givenName: "Ada",
familyName: "Lovelace",
emails: [{ address: "ada@example.com", type: "Work", label: null }]
});
GET/_bridge/contacts#

Whether the app has contacts access, without prompting.

C#IContactsBridge.GetAccessAsyncTSContactsBridge.getAccess
Response
200 ContactsAccessResult
ContactsAccessResult · 1 field
accessAccessState
POST/_bridge/contacts/access#

Prompts for contacts access if it has not been decided.

C#IContactsBridge.RequestAccessAsyncTSContactsBridge.requestAccess
Response
200 ContactsAccessResult
ContactsAccessResult · 1 field
accessAccessState
GET/_bridge/contacts/items#

A page of contacts ordered by family then given name, optionally matching a name, phone or email.

C#IContactsBridge.GetContactsAsyncTSContactsBridge.getContacts
ParameterInType
searchquerystring | nulloptional
offsetquerynumberoptional
limitquerynumberoptional
Response
200 ContactPage
ContactPage · 4 fields
itemsContact[]
offsetnumber
limitnumber
hasMorebooleanWhether another page follows.
POST/_bridge/contacts/items#

Creates a contact. It needs a given name, family name or company.

C#IContactsBridge.CreateContactAsyncTSContactsBridge.createContact
Body
application/json · ContactInput
ContactInput · 14 fields
namePrefixstring | null
givenNamestring | null
middleNamestring | null
familyNamestring | null
nameSuffixstring | null
nicknamestring | null
notestring | null
organizationContactOrganization | null
phonesContactPhone[] | null
emailsContactEmail[] | null
addressesContactAddress[] | null
datesContactDate[] | null
relationshipsContactRelationship[] | null
websitesContactWebsite[] | null
Response
200 ContactCreated
ContactCreated · 1 field
idstring
GET/_bridge/contacts/items/{id}#

One contact. Fails with 404 when there is no such contact.

C#IContactsBridge.GetContactAsyncTSContactsBridge.getContact
ParameterInType
idpathstringrequired
Response
200 Contact
Contact · 17 fields
idstring | null
displayNamestring
namePrefixstring | null
givenNamestring | null
middleNamestring | null
familyNamestring | null
nameSuffixstring | null
nicknamestring | null
notestring | null
organizationContactOrganization | null
phonesContactPhone[]
emailsContactEmail[]
addressesContactAddress[]
datesContactDate[]
relationshipsContactRelationship[]
websitesContactWebsite[]
hasPhotobooleanWhether getPhoto has anything to return.
Errors
404Not found
PUT/_bridge/contacts/items/{id}#

Changes the properties set in changes and leaves the rest as they are.

C#IContactsBridge.UpdateContactAsyncTSContactsBridge.updateContact
ParameterInType
idpathstringrequired
Body
application/json · ContactInput
ContactInput · 14 fields
namePrefixstring | null
givenNamestring | null
middleNamestring | null
familyNamestring | null
nameSuffixstring | null
nicknamestring | null
notestring | null
organizationContactOrganization | null
phonesContactPhone[] | null
emailsContactEmail[] | null
addressesContactAddress[] | null
datesContactDate[] | null
relationshipsContactRelationship[] | null
websitesContactWebsite[] | null
Response
200 Contact
Contact · 17 fields
idstring | null
displayNamestring
namePrefixstring | null
givenNamestring | null
middleNamestring | null
familyNamestring | null
nameSuffixstring | null
nicknamestring | null
notestring | null
organizationContactOrganization | null
phonesContactPhone[]
emailsContactEmail[]
addressesContactAddress[]
datesContactDate[]
relationshipsContactRelationship[]
websitesContactWebsite[]
hasPhotobooleanWhether getPhoto has anything to return.
DELETE/_bridge/contacts/items/{id}#

Deletes a contact.

C#IContactsBridge.DeleteContactAsyncTSContactsBridge.deleteContact
ParameterInType
idpathstringrequired
Response
204 No content
GET/_bridge/contacts/items/{id}/photo#

The contact's photo as encoded image bytes. Fails with 404 when it has none.

C#IContactsBridge.GetPhotoAsyncTSContactsBridge.getPhoto
ParameterInType
idpathstringrequired
sizequeryContactPhotoSizeoptional
Response
200 Binary content — Blob in TypeScript, Stream / byte[] in C#
Errors
404Not found

This bridge raises no events — everything it does is a request and its response.

JSON property names are camelCase and enums travel as their names. A ? marks a property the payload may omit;| null one that may be null.

AccessStateenum#

Where a permission stands. Reported by every bridge that needs one; the names match Shiny's own.

"Unknown""NotSupported""NotSetup""Disabled""Restricted""Denied""Available"
ContactPageobject#

A page of contacts.

itemsContact[]
offsetnumber
limitnumber
hasMorebooleanWhether another page follows.
ContactOrganizationobject#
companystring | null
titlestring | null
departmentstring | null
ContactPhoneobject#
numberstring
typePhoneType
labelstring | nullThe label shown on the device, for a Custom type.
PhoneTypeenum#
"Home""Mobile""Work""FaxWork""FaxHome""Pager""Other""Custom"
ContactEmailobject#
addressstring
typeEmailType
labelstring | nullThe label shown on the device, for a Custom type.
EmailTypeenum#
"Home""Work""Other""Custom"
ContactAddressobject#
streetstring | null
citystring | null
statestring | null
postalCodestring | null
countrystring | null
typeAddressType
labelstring | nullThe label shown on the device, for a Custom type.
AddressTypeenum#
"Home""Work""Other""Custom"
ContactDateobject#
datestring
typeContactDateType
labelstring | nullThe label shown on the device, for a Custom type.
ContactDateTypeenum#
"Birthday""Anniversary""Other""Custom"
ContactRelationshipobject#
namestringThe related person's name.
typeRelationshipType
labelstring | nullThe label shown on the device, for a Custom type.
RelationshipTypeenum#
"Father""Mother""Parent""Brother""Sister""Child""Friend""Spouse""Partner""Assistant""Manager""Other""Custom"
ContactWebsiteobject#
urlstring
labelstring | null
ContactInputobject#

A contact to create, or the changes to one. A property left null is left as it is; an empty list clears. Names and organization fields are at most 1,000 characters, the note 10,000, and each list 50 entries.

namePrefix?string | null
givenName?string | null
middleName?string | null
familyName?string | null
nameSuffix?string | null
nickname?string | null
note?string | null
organization?ContactOrganization | null
phones?ContactPhone[] | null
emails?ContactEmail[] | null
addresses?ContactAddress[] | null
dates?ContactDate[] | null
relationships?ContactRelationship[] | null
websites?ContactWebsite[] | null
ContactCreatedobject#
idstring
ContactPhotoSizeenum#

Which photo to fetch. Each falls back to the other when the contact only has one.

"Full""Thumbnail"

These routes sit under AppDeviceBridgePolicies.Bridges like every other bridge: callers on this device by default. See Security.