Customers

Customer data in go~mus - with foreign_id as the bridge to your CRM. Create, find, update without your system and ours drifting apart.

A customer in go~mus is the natural or legal person who places an order - the contact who receives tickets, gets invoiced, gets newsletters. If you connect your own CRM, membership management or a schools portal to go~mus, the customers resource is the bridge.

The central mechanism: foreign_id. An optional string field where you write your system's id. With it you can find and update customers in go~mus via your external key, without maintaining a lookup table.

Full endpoint and schema reference: Swagger.

The foreign_id pattern

In a typical CRM integration you have a unique customer id in your system (SF-12345, BREVO-abcde, MEMBER-2026-007). You want that id in go~mus too, without juggling go~mus ids.

Solution: set foreign_id on creation:

curl -X POST "https://demo.gomus.de/api/v4/customers" \
  -H "Authorization: Bearer YOUR_API_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "foreign_id": "SF-12345",
      "name": "Müller", "surname": "Anna",
      "email": "anna@example.com"
    }
  }'

After that, lookup and update with your id instead of the go~mus id:

curl "https://demo.gomus.de/api/v4/customers/SF-12345" \
  -H "Authorization: Bearer YOUR_API_USER_TOKEN"

curl -X PUT "https://demo.gomus.de/api/v4/customers/SF-12345" \
  -H "Authorization: Bearer YOUR_API_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "customer": { "tel": "+49 30 99887766" } }'

The server tries the numeric id first, then falls back to foreign_id - your code becomes much shorter than with a lookup table.

Endpoints at a glance

EndpointWhatAuth
GET /api/v4/customers/salutationsAvailable salutations (Frau, Herr, divers, ...)Public
GET /api/v4/customers/titlesAvailable titles (Dr., Prof., ...)Public
POST /api/v4/customersCreate customer (also batch)API user with permission
GET /api/v4/customers/:idCustomer detail (id or foreign_id)API user
PUT /api/v4/customers/:idUpdate customerAPI user with permission
PUT /api/v4/customersBatch update via foreign_idAPI user
DELETE /api/v4/customers/:idDelete customerAPI user with permission

All endpoints except salutations and titles require an authenticated API user. Public tokens are not enough.

Anatomy of a customer object

Master data:

  • id - go~mus primary key
  • foreign_id - your external id (optional but recommended for CRM sync)
  • name, surname
  • email, tel, mobile, fax
  • customer_salutation_id, customer_title_id - salutation and title via existing ids (see salutations/titles)
  • is_institution - boolean: organization, not a private person
  • institution - organization name if is_institution: true
  • notes - free-text notes
  • language_id - preferred language for email templates
  • date_of_birth - if age-relevant
  • vat_number - VAT id

Address as a sub-object: all address fields are passed with prefix addr_:

  • addr_street, addr_zip, addr_city, addr_country_id
  • addr_institution_id - if linked to a stored institution
  • addr_category - price group for this address (PTA name or id)

On update, addr_* fields apply to the customer's first address.

Common tasks

Load salutations and titles (for forms)

curl "https://demo.gomus.de/api/v4/customers/salutations?locale=de"
curl "https://demo.gomus.de/api/v4/customers/titles?locale=de"

Public, no token needed. Returns ids you use as customer_salutation_id / customer_title_id on creation.

Create a customer

curl -X POST "https://demo.gomus.de/api/v4/customers" \
  -H "Authorization: Bearer YOUR_API_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "foreign_id": "MEMBER-2026-007",
      "name": "Schmidt", "surname": "Lukas",
      "email": "lukas@example.com",
      "tel": "+49 30 12345",
      "is_institution": false,
      "addr_street": "Beispielallee 12",
      "addr_zip": "10115",
      "addr_city": "Berlin",
      "addr_country_id": 1
    }
  }'

Response: the created customer object with id and all set fields.

Create customers in a batch

curl -X POST "https://demo.gomus.de/api/v4/customers" \
  -H "Authorization: Bearer YOUR_API_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": [
      { "foreign_id": "M-001", "name": "Schmidt", "surname": "Lukas", "email": "..." },
      { "foreign_id": "M-002", "name": "Meier", "surname": "Tina", "email": "..." }
    ]
  }'

An array instead of a single object. There is an instance-specific cap per batch - send very large imports in several calls.

Find a customer by foreign_id

curl "https://demo.gomus.de/api/v4/customers/MEMBER-2026-007" \
  -H "Authorization: Bearer YOUR_API_USER_TOKEN"

The server tries the numeric id first, falls back to foreign_id. Clean precondition: your foreign_id format does not collide with numeric ids.

Update a customer

curl -X PUT "https://demo.gomus.de/api/v4/customers/MEMBER-2026-007" \
  -H "Authorization: Bearer YOUR_API_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "tel": "+49 30 99887766",
      "addr_street": "Neue Straße 5"
    }
  }'

Fields that are not in the body stay untouched.

Batch update via foreign_id

curl -X PUT "https://demo.gomus.de/api/v4/customers" \
  -H "Authorization: Bearer YOUR_API_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": [
      { "foreign_id": "M-001", "tel": "+49 30 11..." },
      { "foreign_id": "M-002", "email": "tina-new@..." }
    ]
  }'

Per entry, foreign_id is the key - go~mus finds the matching customer and updates the supplied fields.

Customer in the order

When creating an order there are two ways to attach a customer:

  • Customer data inline in the order body - go~mus creates a customer or finds an existing one by email
  • Reference a customer id - if you already created the customer, just attach customer_id (or foreign_id) on the order

Pattern for CRM sync: create the customer with foreign_id first, then reference it in the order. Your records stay linked across both systems.

Relationships

Customer
 ├── foreign_id ............. your external id (optional)
 ├── CustomerSalutation ..... salutation
 ├── CustomerTitle .......... title
 ├── CustomerAddress (1..n) . first one is updated via addr_*
 ├── Institution (via addr)  if institutional
 ├── PriceTargetAudience .... price group
 ├── Order (0..n) ........... orders by this person
 └── NewsletterSubscription (0..n)

Pitfalls

  • API-user auth is mandatory. Customer endpoints (except salutations/titles) are not public. Never embed the token in the frontend - relay server-side.
  • Do not let foreign_id overlap with numeric ids. If your CRM ids happen to look like go~mus ids (12345), the lookup tries the numeric id first - you may not see the customer you expect. Prefixes like SF-, MEMBER-, BREVO- are your friends.
  • Address update only touches the first address. addr_* fields in the update target the customer's first address. If you maintain multiple addresses (billing vs shipping), you must sync those outside the customer endpoints.
  • Customers have order and newsletter ties. A customer delete does not cascade - orders and newsletter subscriptions stay. For GDPR-compliant deletion, be aware of the order references in your own code and anonymize or delete first.
  • Fetch salutations/titles before creating. The ids are instance-specific (custom salutations are possible). Cache the list locally but fetch it fresh once at setup.
  • Mind the batch limit. Otherwise you get customer(s) could not be saved with detail errors.
  • Authentication - API user token, permissions, foreign_id in the order context
  • Best Practices - foreign_id for customer mapping, idempotency
  • Errors - 422 validation errors on customer creation
  • Concepts - order, foreign_id pattern