Tiquo
Integrations OverviewAirtableAsanaSlackGoogle AnalyticsMetabaseMixpanelPendoSegmentTableau (PAT)ActiveCampaignBrevoEmarsys Core API (WSSE)EventbriteFacebookGoogle AdsHighLevelInstagramKlaviyoMailchimpMailgunMicrosoft AdsSendGridTwitter (v2)HubSpotNotionAcuity SchedulingAirtable (Personal Access Token)BasecampCal.com (v2)CalendlyClickUpCodaConfluence Data CenterExpensifyGoogle CalendarGoogle SheetHarvestLinearMicrosoft Power BIMicrosoft TeamsMindbodyMondayOpenAIPerplexityPingboardPivotal TrackerProductboardQuickbaseServiceM8ServiceNowTeamworkTickTickTimelyTodoistTrafftTrelloWrikefal.aixAIZendeskIntercomAircall (OAuth)DixaFreshDeskFreshserviceFrontPlainRingCentralZoho DeskBrazeDialpadGoogleMicrosoftOutlookPodiumSednaSharePoint OnlineTwilioWhatsApp BusinessZoho MailBambooHRADPDeelEmployment HeroGustoHibob Service UserNamelyOracle Fusion Cloud (HCM)PaychexPayfitPaylocityPersonioRipplingSAP SuccessFactorsSage HRTSheetsUKG ProUKG ReadyWorkdayZoho PeopleQuickBooksBuildiumExact OnlineFreshBooksIntuitNetSuitePennylaneSageSage IntacctTwinfieldUnanetWave AccountingXeroZoho BooksSalesforceAffinityAttioCopperFreshsalesGainsight CCInsightlyKustomerMedalliaPipedriveTwenty CRMZoomInfoApaleoMewsMicrosoft Business CentralOdooSAP ConcurZuoraAcceloCoupa CompassZoho InvoiceAnrokAvalaraDocuSignDropbox SignPandadocSignNowLinkedInSplitwiseTikTok AdsJotformQualtricsRefinerTypeformShopifyCin7 CoreGoogle MapsRingoverListrakRydooTalentLMSApple Business ManagerCrunchbaseRocketReachOcean.ioFreepikEnergy Performance Certificates (Gov.UK)JustworksGristSAP S/4HANA Cloud3CX8x8Adobe CommerceBirdCloudbedsConstant ContactBufferCustomer.ioCrispFreeAgentGreenhouseMeta Marketing APIMollienocrm.ioOomnitzaDigitsPylonSage 200ShopwareAnvilShippoEasyPostAltrataMicrosoft PeopleMicrosoft IntuneCloudTalkGoogle FormsMaximizerMicrosoft PlannerSalesmsgSellercloudTallyTimifyUpsalesCleverReachHeymarketMailjetPleoProvenExpertTelegramToggl TrackTenzoASSA ABLOY Vingcard VisionlineASSA ABLOY Vingcard VostioASSA ABLOY TESA HotelASSA ABLOY SMARTairSalto KSSalto Space OnlineDormakabaOmnitecHotekTT LockWebLockISEOKleverKeyAperioISONASHIDSouthcoThird MillenniumSTidAxis CommunicationsBooking.comExpediaHotels.comAirbnbGoogle HotelsTripadvisorAgodaHotelbedsTravelgateXHyperguestRoibosReconlineTraviaOpenGDS.comMG BedbankDidatravelHotelREZHRSHotelnetworkGetaroomWinkBookeasyVRBOInntopiaHookusbookusHipcampSpot2niteCamping VisionMinistry of VillasTrip.comTravelokaTiketMakeMyTripHoteripKlookeDreamsSzallasEmerging Travel GroupCheck24Bed-and-Breakfast.itWorld2Meet (W2M)Ctoutvert / SecureholidayDespegarPriceTravelRoombeastMitchell CorpHRS AustraliaResonlineHostelworldHostelhopTablet MichelinMr & Mrs SmithHopperHotel TonightPitchupMoveriiLocalOTAAlaricBooknpayCultbookingGuestTractionLevartWeSpeakMake.comZapierPricelabsPricepointRategenieElastic HotelRoom Price GenieTurbosuiteUber EatsDeliverooDoorDashBolt FoodGlovo
API and AuthenticationCustomer API

Update Profile

Update the authenticated customer's profile fields

Update Profile

Update one or more fields on the authenticated customer's profile. Only the fields you include in the request body will be changed.

Endpoint

PATCH /profile

Authentication

Requires a valid JWT access token.

Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...

Request Body

For an existing profile, all fields are optional and only included fields are changed. If the authenticated account does not yet have a customer profile, this endpoint creates and links one; firstName is then required.

FieldTypeDescription
firstNamestringCustomer's first name
lastNamestringCustomer's last name
phonestringPhone number (e.g. +1234567890)
profilePhotostringURL to a profile photo
profileParametersobjectEditable customer parameters keyed by parameter ID or name
emailsarrayFull email list using { address, isPrimary, order } entries
phonesarrayFull phone list using { number, isPrimary, order } entries

displayName is read-only. Tiquo derives it from firstName and lastName whenever either name changes.

When both phones and phone are supplied, the full phones array takes precedence. Sending an empty phone removes the current primary phone. Parameter values are validated against the organization's customer-editable parameter definitions.

During initial profile creation, the account email from the JWT becomes the primary email and the single phone field is used. Apply full emails or phones arrays in a later update after the profile exists.

The DOM Package also accepts a browser File or Blob for profilePhoto. When a file is provided, the SDK uploads the image through the profile photo upload endpoints before saving the customer profile.

createdAt and firstActiveAt are read-only system fields. They are returned on the customer object but are not accepted as profile updates. The Hosted and DOM packages also remove these fields from dynamically constructed update payloads.

New secondary email addresses cannot be introduced through PATCH /profile. Verify ownership with the two endpoints below first.

Add a Verified Secondary Email

Send a verification code

POST /profile/email-verification/send
curl -X POST "https://edge.tiquo.app/api/client/v1/profile/email-verification/send" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..." \
  -H "Content-Type: application/json" \
  -d '{"email":"second@example.com","portalSlug":"members"}'

portalSlug is optional and selects the portal branding for the verification email. The six-digit code expires after 10 minutes.

Verify and add the address

POST /profile/email-verification/verify
curl -X POST "https://edge.tiquo.app/api/client/v1/profile/email-verification/verify" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..." \
  -H "Content-Type: application/json" \
  -d '{"email":"second@example.com","otp":"123456"}'
{
  "success": true,
  "data": {
    "email": "second@example.com",
    "emails": [
      { "address": "customer@example.com", "isPrimary": true, "order": 0 },
      { "address": "second@example.com", "isPrimary": false, "order": 1 }
    ]
  }
}

A profile can have up to five email addresses. The new address must not already be on this profile or another customer profile in the organization. Send and verify requests are rate limited, and repeated incorrect codes require a new code.

Example Request

curl -X PATCH "https://edge.tiquo.app/api/client/v1/profile" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "John",
    "lastName": "Smith",
    "phone": "+1234567890"
  }'

Response

{
  "success": true,
  "data": {
    "customer": {
      "id": "cust_456",
      "firstName": "John",
      "lastName": "Smith",
      "displayName": "John Smith",
      "customerNumber": "CUST-000001",
      "email": "customer@example.com",
      "phone": "+1234567890",
      "profilePhoto": null,
      "createdAt": 1704067200000,
      "firstActiveAt": 1706745600000,
      "emails": [
        { "address": "customer@example.com", "isPrimary": true, "order": 0 }
      ],
      "phones": [
        { "number": "+1234567890", "isPrimary": true, "order": 0 }
      ],
      "parameters": [],
      "parameterValues": {}
    }
  }
}

For an existing profile, a successful response is 200 OK and includes the updated customer at both customer and data.customer.

When the endpoint creates a missing profile, it returns 201 Created. The new customer is always available at the top-level customer property. If profileParameters were also applied, the response additionally includes data.customer.

Profile Photo Uploads

For browser-based uploads, use the DOM Package uploadProfilePhoto() helper where possible.

If you are calling the Customer API directly, profile photo uploads use two steps:

  1. Request an upload URL.
  2. Upload the image to that URL, then finalise the profile photo with the returned storageId.

Create Upload URL

POST /profile/photo-upload-url

The request body can be an empty JSON object.

curl -X POST "https://edge.tiquo.app/api/client/v1/profile/photo-upload-url" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..." \
  -H "Content-Type: application/json" \
  -d '{}'

The response includes a temporary uploadUrl.

{
  "success": true,
  "data": {
    "uploadUrl": "https://..."
  }
}

Upload the image file to the returned URL using POST and the image content type. The upload response includes a storageId.

Finalise Profile Photo

POST /profile/photo
curl -X POST "https://edge.tiquo.app/api/client/v1/profile/photo" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "storageId": "kg2..."
  }'

The upload must be a JPEG, PNG, GIF, or WebP image and be no larger than 5 MB.

The response includes the updated customer, the resolved profilePhoto URL, and the storageId.

Errors

StatusDescription
400First name is missing during profile creation, or one or more field or parameter values are invalid
401Invalid or expired access token
500Internal server error

Code Examples

JavaScript

const response = await fetch('https://edge.tiquo.app/api/client/v1/profile', {
  method: 'PATCH',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    firstName: 'John',
    lastName: 'Smith',
  }),
});

const { success, customer, data, error } = await response.json();

if (success) {
  const updatedCustomer = data?.customer ?? customer;
  console.log('Profile updated:', updatedCustomer.displayName);
}

Swift

var request = URLRequest(url: URL(string: "https://edge.tiquo.app/api/client/v1/profile")!)
request.httpMethod = "PATCH"
request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONEncoder().encode(["firstName": "John", "lastName": "Smith"])

let (data, _) = try await URLSession.shared.data(for: request)

Kotlin

val body = """{"firstName": "John", "lastName": "Smith"}"""
    .toRequestBody("application/json".toMediaType())

val request = Request.Builder()
    .url("https://edge.tiquo.app/api/client/v1/profile")
    .patch(body)
    .addHeader("Authorization", "Bearer $accessToken")
    .build()

val response = client.newCall(request).execute()

Sur cette page