> ## Documentation Index
> Fetch the complete documentation index at: https://kardow.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sync Member

> Create or update a member and optionally sync access and a payment in a single call

Use this when one external workflow should make the member record correct in one request.

Typical uses:

* create a member if they do not exist yet
* update role, approval state, profile data, or custom fields
* attach or update a subscription
* record a payment at the same time

## Core Inputs

<ParamField body="email" type="string" required>
  Primary identifier for the member.
</ParamField>

<ParamField body="name" type="string">
  Display name. If omitted, Kardow falls back to the email prefix.
</ParamField>

<ParamField body="role" type="string">
  `employee`, `business`, `both`, `jobseeker`, or `employer`.
</ParamField>

<ParamField body="approvalStatus" type="string">
  Explicitly set `approved`, `pending`, or `rejected` when your workflow controls approval.
</ParamField>

<ParamField body="customFields" type="object">
  Extra answers or profile fields to store with the member.
</ParamField>

<ParamField body="access" type="object">
  Optional subscription sync block. Use `stripePriceId`, `paypalPlanId`, `planId`, or `planName` to identify the plan.
</ParamField>

<ParamField body="payment" type="object">
  Optional payment block. `jobId`, `amount`, and `currency` are required if you send it.
</ParamField>

## Examples

### Create a basic member

```bash cURL theme={null}
curl --request POST \
  --url https://api.kardow.com/members/sync \
  --header "Content-Type: application/json" \
  --header "x-api-key: your-api-key-here" \
  --data '{
    "email": "member@example.com",
    "name": "Taylor Member",
    "role": "employee"
  }'
```

### Create an employer and force approval

```bash cURL theme={null}
curl --request POST \
  --url https://api.kardow.com/members/sync \
  --header "Content-Type: application/json" \
  --header "x-api-key: your-api-key-here" \
  --data '{
    "email": "owner@example.com",
    "role": "business",
    "approvalStatus": "approved",
    "customFields": {
      "company_size": "51-200",
      "website": "https://example.com"
    }
  }'
```

### Grant paywall access in the same call

```bash cURL theme={null}
curl --request POST \
  --url https://api.kardow.com/members/sync \
  --header "Content-Type: application/json" \
  --header "x-api-key: your-api-key-here" \
  --data '{
    "email": "subscriber@example.com",
    "role": "employee",
    "access": {
      "stripePriceId": "price_paywall_monthly",
      "status": "active"
    }
  }'
```

### Create a bundle subscription and payment together

```bash cURL theme={null}
curl --request POST \
  --url https://api.kardow.com/members/sync \
  --header "Content-Type: application/json" \
  --header "x-api-key: your-api-key-here" \
  -d '{
    "email": "poster@example.com",
    "role": "business",
    "approvalStatus": "approved",
    "access": {
      "stripePriceId": "price_bundle_10",
      "status": "active"
    },
    "payment": {
      "jobId": "44444444-4444-4444-4444-444444444444",
      "amount": 199,
      "currency": "USD",
      "status": "completed",
      "paymentProvider": "invoice"
    }
  }'
```

### Update an existing member without changing billing

```bash cURL theme={null}
curl --request POST \
  --url https://api.kardow.com/members/sync \
  --header "Content-Type: application/json" \
  --header "x-api-key: your-api-key-here" \
  --data '{
    "email": "member@example.com",
    "name": "Taylor Updated",
    "role": "both",
    "customFields": {
      "department": "Product"
    }
  }'
```

## Response Shape

<ResponseField name="data.member" type="object" required>
  The organization-scoped member record.
</ResponseField>

<ResponseField name="data.access" type="object">
  The updated subscription when an `access` block is sent.
</ResponseField>

<ResponseField name="data.payment" type="object">
  The created payment when a `payment` block is sent.
</ResponseField>

<ResponseField name="data.created" type="boolean" required>
  `true` when the member was newly created in this organization.
</ResponseField>

### Example response

```json theme={null}
{
  "data": {
    "member": {
      "id": "11111111-1111-1111-1111-111111111111",
      "organizationId": 42,
      "email": "member@example.com",
      "name": "Taylor Member",
      "role": "employee",
      "approvalStatus": "approved",
      "profilePicture": null,
      "description": null,
      "customFields": null
    },
    "access": null,
    "payment": null,
    "created": true
  }
}
```


## OpenAPI

````yaml POST /members/sync
openapi: 3.1.0
info:
  title: Kardow Public API
  description: Public API for jobs and member automation on Kardow.
  version: 1.0.0
  contact:
    name: Kardow Support
    email: support@kardow.com
    url: https://kardow.com
servers:
  - url: https://api.kardow.com
    description: Production API
security:
  - ApiKeyAuth: []
paths:
  /members/sync:
    post:
      tags:
        - Members
      summary: Sync Member
      description: >-
        Create or update a member, optionally syncing access and a payment in
        the same request.
      operationId: syncMember
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SyncMemberRequest'
            examples:
              basic_member:
                summary: Create basic member
                value:
                  email: member@example.com
                  name: Taylor Member
                  role: employee
              approval_fields:
                summary: Employer with approval and custom fields
                value:
                  email: owner@example.com
                  role: business
                  customFields:
                    company_size: 51-200
                    website: https://example.com
              paywall_access:
                summary: Create member with paywall access
                value:
                  email: subscriber@example.com
                  role: employee
                  access:
                    stripePriceId: price_paywall_monthly
                    status: active
              bundle_and_payment:
                summary: Bundle quota plus payment record
                value:
                  email: poster@example.com
                  role: business
                  approvalStatus: approved
                  access:
                    stripePriceId: price_bundle_10
                    status: active
                  payment:
                    jobId: 44444444-4444-4444-4444-444444444444
                    amount: 199
                    currency: USD
                    status: completed
                    paymentProvider: invoice
      responses:
        '200':
          description: Updated existing member
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SyncMemberResponse'
        '201':
          description: Created member
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SyncMemberResponse'
        '400':
          $ref: '#/components/responses/ValidationError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '403':
          $ref: '#/components/responses/ForbiddenError'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ApiKeyAuth: []
components:
  schemas:
    SyncMemberRequest:
      type: object
      required:
        - email
      properties:
        userId:
          type: string
          format: uuid
        email:
          type: string
          format: email
        name:
          type: string
        role:
          type: string
          enum:
            - employee
            - business
            - both
            - jobseeker
            - employer
        approvalStatus:
          type: string
          enum:
            - approved
            - pending
            - rejected
        profilePicture:
          type:
            - string
            - 'null'
          format: uri
        description:
          type:
            - string
            - 'null'
        customFields:
          type:
            - object
            - 'null'
          additionalProperties: true
        access:
          type: object
          properties:
            planId:
              type: string
              format: uuid
            stripePriceId:
              type: string
            paypalPlanId:
              type: string
            planName:
              type: string
            subscriptionId:
              type: string
              format: uuid
            stripeSubscriptionId:
              type: string
            status:
              type: string
              default: active
            startsAt:
              type: string
              format: date-time
            endsAt:
              type: string
              format: date-time
            jobsRemaining:
              type:
                - integer
                - 'null'
            metadata:
              type:
                - object
                - 'null'
              additionalProperties: true
        payment:
          type: object
          properties:
            jobId:
              type: string
              format: uuid
            planId:
              type: string
              format: uuid
            stripePriceId:
              type: string
            paypalPlanId:
              type: string
            planName:
              type: string
            amount:
              type: number
            currency:
              type: string
            status:
              type: string
            paymentProvider:
              type:
                - string
                - 'null'
            stripeSessionId:
              type:
                - string
                - 'null'
            stripePaymentIntentId:
              type:
                - string
                - 'null'
            metadata:
              type:
                - object
                - 'null'
              additionalProperties: true
          required:
            - jobId
            - amount
            - currency
    SyncMemberResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            member:
              $ref: '#/components/schemas/Member'
            access:
              oneOf:
                - $ref: '#/components/schemas/Subscription'
                - type: 'null'
            payment:
              oneOf:
                - $ref: '#/components/schemas/Payment'
                - type: 'null'
            created:
              type: boolean
          required:
            - member
            - created
      required:
        - data
    Member:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: integer
        email:
          type: string
          format: email
        name:
          type: string
        role:
          type: string
        approvalStatus:
          type: string
        authMethod:
          type:
            - string
            - 'null'
          description: How the member authenticates (e.g. password, oauth).
        profilePicture:
          type:
            - string
            - 'null'
        description:
          type:
            - string
            - 'null'
        customFields:
          type:
            - object
            - 'null'
          additionalProperties: true
    Subscription:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: integer
        userId:
          type: string
          format: uuid
        planId:
          type: string
          format: uuid
        status:
          type: string
        stripeSubscriptionId:
          type:
            - string
            - 'null'
        currentPeriodStart:
          type:
            - string
            - 'null'
          format: date-time
        currentPeriodEnd:
          type:
            - string
            - 'null'
          format: date-time
        cancelAt:
          type:
            - string
            - 'null'
          format: date-time
        canceledAt:
          type:
            - string
            - 'null'
          format: date-time
        jobsRemaining:
          type:
            - integer
            - 'null'
        metadata:
          type:
            - object
            - 'null'
          additionalProperties: true
    Payment:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: integer
        userId:
          type: string
          format: uuid
        jobId:
          type: string
          format: uuid
        planId:
          type: string
          format: uuid
        amount:
          type: number
        currency:
          type: string
        status:
          type: string
        paymentProvider:
          type:
            - string
            - 'null'
        stripeSessionId:
          type:
            - string
            - 'null'
        stripePaymentIntentId:
          type:
            - string
            - 'null'
        metadata:
          type:
            - object
            - 'null'
          additionalProperties: true
    ErrorEnvelope:
      type: object
      properties:
        error:
          type: object
          properties:
            message:
              type: string
            code:
              type: string
            details: {}
            url:
              type: string
          required:
            - message
            - code
      required:
        - error
  responses:
    ValidationError:
      description: Validation error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    UnauthorizedError:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    ForbiddenError:
      description: Forbidden
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        API key for authentication. Get yours from Settings > API Keys in the
        Kardow dashboard.

````