Galaxy Unit Contacts API
The Contacts API from Galaxy Unit — 2 operation(s) for contacts.
The Contacts API from Galaxy Unit — 2 operation(s) for contacts.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/galaxyunit-app:galaxyunit-app-contacts-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Galaxy Unit Contacts API
version: 1.0.0
description: 'REST for AI agents and scripts. A key acts as the member who made it (never above admin) under row-level security. Money is a decimal string. Dates are YYYY-MM-DD in the business time zone (see /me). Errors carry code, field and a hint the agent can act on. Read /for-agents first: https://galaxyunit.app/for-agents'
contact:
url: https://galaxyunit.app/contact
termsOfService: https://galaxyunit.app/terms
servers:
- url: https://app.galaxyunit.app
security:
- apiKey: []
tags:
- name: Contacts
paths:
/api/v1/contacts:
get:
operationId: contactsList
summary: List contacts (newest updated first, cursor pages)
parameters:
- name: q
in: query
description: ILIKE on name, company_name, email, boat_name, marina
schema:
type: string
maxLength: 100
- name: updated_since
in: query
schema:
type: string
format: date-time
- name: limit
in: query
schema:
type: integer
maximum: 200
default: 50
- name: cursor
in: query
description: next_cursor from the previous page
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
type: object
properties:
id: {}
name: {}
company_name: {}
is_company: {}
phone: {}
email: {}
marina: {}
boat_name: {}
boat_length_ft: {}
boat_model: {}
boat_year: {}
dock_slip: {}
billing_address: {}
billing_city: {}
billing_province: {}
billing_postal: {}
billing_email: {}
client_hst_number: {}
status: {}
lead_source: {}
tags: {}
notes: {}
version: {}
created_at: {}
updated_at: {}
next_cursor:
type:
- string
- 'null'
'401':
description: Missing or invalid key
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'402':
description: Plan required
content:
application/json:
schema:
type: object
description: Answered with HTTP 402 when a plan is required. Relay message_for_owner and approve_url to the human, then retry the same call.
properties:
code:
const: PLAN_REQUIRED
needed:
type: string
for:
type: string
what_you_get:
type: array
items:
type: string
price:
type:
- object
- 'null'
approve_url:
type: string
trial_url:
type:
- string
- 'null'
message_for_owner:
type: string
retryable:
const: true
'403':
description: Key lacks scope or member lacks role
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'422':
description: Validation error (see field, hint)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'429':
description: Rate limited (Retry-After)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
tags:
- Contacts
post:
operationId: contactsCreate
summary: Create a contact (write scope).
parameters:
- name: Idempotency-Key
in: header
required: true
schema:
type: string
minLength: 8
maxLength: 128
- name: dry_run
in: query
schema:
type: string
enum:
- '1'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
phone:
type: string
email:
type: string
company_name:
type: string
marina:
type: string
description: Location (marina / site / address — whatever this industry uses)
boat_name:
type: string
description: Object reference (boat / vehicle / property name)
boat_length_ft:
type: number
exclusiveMinimum: 0
maximum: 9999
description: Object size (boat length ft, area sqft, …) — drives size-based pricing. Must be > 0 and <= 9999; omit it rather than guessing
notes:
type: string
required:
- name
additionalProperties: false
description: Add a client/contact. Use for "add a client", "new customer".
responses:
'202':
description: 'Waiting for the owner: nothing written yet. The owner got an email to approve; poll GET /api/v1/actions/{action_id}.'
content:
application/json:
schema:
$ref: '#/components/schemas/PendingAction'
'401':
description: Missing or invalid key
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'402':
description: Plan required
content:
application/json:
schema:
type: object
description: Answered with HTTP 402 when a plan is required. Relay message_for_owner and approve_url to the human, then retry the same call.
properties:
code:
const: PLAN_REQUIRED
needed:
type: string
for:
type: string
what_you_get:
type: array
items:
type: string
price:
type:
- object
- 'null'
approve_url:
type: string
trial_url:
type:
- string
- 'null'
message_for_owner:
type: string
retryable:
const: true
'403':
description: Key lacks scope or member lacks role
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'404':
description: Named client/job not found in this business
'422':
description: Validation error (see field, hint)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'429':
description: Rate limited (Retry-After)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
tags:
- Contacts
/api/v1/contacts/{id}:
patch:
operationId: contactsUpdate
summary: Update a contact (write scope).
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
- name: If-Match
in: header
required: true
schema:
type: integer
minimum: 1
description: data.version from the last GET
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
contact:
type: string
description: Which client — the name (or boat / company) however the user referred to them
name:
type: string
description: New name — only when the user is renaming the client
phone:
type: string
email:
type: string
company_name:
type: string
marina:
type: string
description: Location (marina / site / address — whatever this industry uses)
boat_name:
type: string
description: Object reference (boat / vehicle / property name)
boat_length_ft:
type: number
exclusiveMinimum: 0
maximum: 9999
description: Object size (boat length ft, area sqft, …) — must be > 0 and <= 9999
boat_model:
type: string
boat_year:
type: integer
minimum: -9007199254740991
maximum: 9007199254740991
description: 4-digit year
dock_slip:
type: string
description: Slip / unit / bay number
notes:
type: string
description: REPLACES the notes field
billing_address:
type: string
billing_city:
type: string
billing_province:
type: string
billing_postal:
type: string
billing_email:
type: string
client_hst_number:
type: string
description: Client tax number as printed on their documents
required:
- contact
additionalProperties: false
description: 'Change an EXISTING client/contact: phone, email, location (marina), object (boat) name / size / model / year, slip, notes, billing address, company or name. Use for "поменяй телефон Janet", "Sarah moved to Bluffers Park", "update Mike''s boat length to 40". Only pass the fields being changed — everything omitted is left exactly as it is. NEVER create a second contact to "fix" one; to add a NEW client use create_contact. For jobs use update_job. Only the fields being changed; the id comes from the path.'
responses:
'202':
description: 'Waiting for the owner: nothing written yet. The owner got an email to approve; poll GET /api/v1/actions/{action_id}.'
content:
application/json:
schema:
$ref: '#/components/schemas/PendingAction'
'401':
description: Missing or invalid key
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'402':
description: Plan required
content:
application/json:
schema:
type: object
description: Answered with HTTP 402 when a plan is required. Relay message_for_owner and approve_url to the human, then retry the same call.
properties:
code:
const: PLAN_REQUIRED
needed:
type: string
for:
type: string
what_you_get:
type: array
items:
type: string
price:
type:
- object
- 'null'
approve_url:
type: string
trial_url:
type:
- string
- 'null'
message_for_owner:
type: string
retryable:
const: true
'403':
description: Key lacks scope or member lacks role
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'404':
description: Not found in this business
'412':
description: 'Version conflict: body.current holds the row as it is now'
'422':
description: Validation error (see field, hint)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'428':
description: If-Match missing
'429':
description: Rate limited (Retry-After)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
tags:
- Contacts
get:
operationId: contactsGet
summary: One contact by id
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
id: {}
name: {}
company_name: {}
is_company: {}
phone: {}
email: {}
marina: {}
boat_name: {}
boat_length_ft: {}
boat_model: {}
boat_year: {}
dock_slip: {}
billing_address: {}
billing_city: {}
billing_province: {}
billing_postal: {}
billing_email: {}
client_hst_number: {}
status: {}
lead_source: {}
tags: {}
notes: {}
version: {}
created_at: {}
updated_at: {}
'401':
description: Missing or invalid key
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'402':
description: Plan required
content:
application/json:
schema:
type: object
description: Answered with HTTP 402 when a plan is required. Relay message_for_owner and approve_url to the human, then retry the same call.
properties:
code:
const: PLAN_REQUIRED
needed:
type: string
for:
type: string
what_you_get:
type: array
items:
type: string
price:
type:
- object
- 'null'
approve_url:
type: string
trial_url:
type:
- string
- 'null'
message_for_owner:
type: string
retryable:
const: true
'403':
description: Key lacks scope or member lacks role
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'404':
description: Not found in this business
'422':
description: Validation error (see field, hint)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'429':
description: Rate limited (Retry-After)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
tags:
- Contacts
components:
schemas:
PendingAction:
type: object
required:
- status
- action_id
properties:
status:
type: string
const: pending_confirmation
action_id:
type: string
format: uuid
expires_at:
type: string
format: date-time
message_for_owner:
type: string
hint:
type: string
securitySchemes:
apiKey:
type: http
scheme: bearer
description: 'Authorization: Bearer gu_live_… — issued in Settings → Integrations by an owner or admin.'