# Changing customer data

The /api/customers/update/ endpoint processes an array of operations to be performed on customers and related subscriptions and product assignments.

# Parameters

The endpoint uses POST and currently supports the following single parameter:

  • "operations" - a JSON array of operation objects, e.g. operations=[{ "operation": "updatecustomer", "id": "123456", "data": { "name": "Customer Name" }}]

Each operation object has "operation" with the name of the operation to perform, and "id" as the ID of the customer to perform the operation on (except for the create customer operation where it is optional).

# Operation errors

If the JSON in the operations is bad or a required parameter to an operation is completely missing in the JSON, i.e. there has been a programming error, a HTTP 400 error is returned with an explanation.

The provided operations are also checked for other basic runtime errors. If something is found to be invalid, e.g. the value of a field which the user may have entered, that operation is skipped and validation errors are returned instead for that operation. The next operations in the array are still processed.

# Return value

The return value is a JSON object with a summary of succeeded and failed operations and the errors, if any.

Validation errors are returned with an array of the same length as the "operations" array you have passed in, with an object (empty if no errors) for each operation with fields and corresponding errors in human-readable form, like this:

{
  "succeeded": 0,
  "failed": 1,
  "errors": [
    {
      ":Custom date field": ["Enter a valid date."]
    }
  ],
  "ids": [null]
}

Errors that are not specific to a field are returned with the empty string as key "". For example:

{
  "succeeded": 0,
  "failed": 1,
  "errors": [
    {
      "": ["Customer does not exist."]
    }
  ],
  "ids": [null]
}

These errors return with an HTTP 200 status code.

# Attributes in "data"

Some of the operations have in common that you can change the fields of the object through a "data" object with some built-in attributes and then any fields set up inside Iteras.

Fields not mentioned in "data" are not touched. Passing a field with a value of null removes the field from the object.

Note that changing the fields adds an entry to the history log inside Iteras summarizing the change. In some cases, e.g. daily synchronizing some statistics where each update really isn't interesting, you can disable history for a specific field you're updating in the field settings.

# Creating a customer and then acting on that customer

In some cases, for instance when importing customers with associated subscriptions, it's convenient to be able to submit a complete set of create operations, even though the IDs necessary to link subscriptions to customers are not yet known.

For this reason, any operation requiring a customer ID can leave out the ID, and instead the ID from a preceding "createcustomer" operation will be used. If there's no preceding create customer operation, an error is raised. Here's an example:

[
  {
    "operation": "createcustomer",
    "data": {
       "email": "someone@example.com"
     }
  }, {
    "operation": "createsubscription", // create subscription for someone@example.com
    "campaign": "3months"
  }
]

# Operation "createcustomer"

Create a new customer. This is useful when importing or synchronizing with other systems. For situations where a customer is actually putting in an order, you should probably use the place order API instead to go get an order registered in Iteras and let that create the subscription. Parameters:

  • "id" - (optional) to force the customer to be created with the specific ID
  • "data" - object with the customer attributes, valid attributes are a few built-in ones and then the customer fields defined inside Iteras

An example:

[
  {
    "operation": "createcustomer",
    "data": {
      "name": "Customer Name",
      "email": "foo@example.com",
      "password": "secret",
      "created": "2010-12-24T12:00:00",
      "tax_registration_id": "DK35681558",
      ":Custom field": "Some value",
      ":Custom date field": "2001-12-31"
    }
  }
]

Supported attributes: Currently you can change attributes that you can get from /api/customers/, with a few small inconsistencies due to backwards compatibility: Use country instead of country_code, and address instead of location.

Additionally, you can set password. You can't retrieve the password in clear text afterwards as it goes through a hash.

You can set an ID to force the customer to be created with the specific ID. Here's an example:

[
  {
    "id": "12345",                   // ID to use for the new customer (optional)
    "operation": "createcustomer",
    "data": {
      "name": "Customer Name",
      ...
    }
  }
]

If the ID is provided and a customer with that ID already exists, an error is thrown. If you instead would like the customer to be updated, use the "updatecustomer" operation with create set to true.

# Operation "updatecustomer"

Changes the attributes of the customer. Parameters:

  • "data" - object with the attributes, valid attributes are a few built-in ones and then the customer fields defined inside Iteras

  • "create" - (optional) if set to true the customer will be created if not found, otherwise an unknown customer ID result in an error being thrown

An example:

[
  {
    "id": "12345",                   // customer ID
    "operation": "updatecustomer",
    "data": {
      "name": "New Name",
      ":Custom field": "Some value",
      ":Custom date field": "2001-12-31",
      ":Obsolete field": null        // passing null deletes the field from the customer
    }
  }
]

Supported attributes: Currently you can change attributes that you can get from /api/customers/, with a few small inconsistencies due to backwards compatibility: Use country instead of country_code, and address instead of location.

Additionally, you can set password. You can't retrieve the password in clear text afterwards as it goes through a hash.

# Operation "createsubscription"

Create a new subscription for a customer. This is useful when importing or synchronizing with other systems. For situations where a customer is actually putting in an order, you should probably use the place order API instead to get an order registered in Iteras and let that create the subscription.

Most of the parameters here are optional and only useful when migrating subscriptions from another system where it can be necessary to adjust the first period.

Parameters:

  • "periods" - list of periods to create, usually you'll just specify one period unless importing historical data from another system, see below

  • "group_subscription_id" - (optional) id of the group subscription controlling this subscription, e.g. "1300312"

  • "data" - (optional) any fields to set on the subscription - the valid fields are the ones associated with the products that the subscription is subscribed to

  • "cancelled" - (optional) set to true if the subscription has been cancelled and should not be renewed

  • "quantity" - (optional) set the quantity of the subscription, e.g. 15

  • "invoiced_by" - (optional) set the invocing method, should be one of "netsdk", "email" or "manual", defaults to "email"

The parameter periods is an array where each element is an object with the following attributes:

  • "campaign_id" - id of the campaign, e.g. "1300" or "3months"

  • "begin" - (optional) set the time to begin the period, e.g. "2024-12-31T00:00:00", you can specify both a time in the past and one in the future - the default is the current time

  • "end" - (optional) override the time to end the period, e.g. "2025-12-31T00:00:00", instead of using the duration specified in the campaign

  • "remaining_assignments" - (optional) override the remaining assignments in the period, e.g. 3, instead of using the full number of assignments specified in the campaign

  • "invoicing" - (optional) set to "none" if the period should not be invoiced, or "adjusted_begin" or "adjusted_end" if you adjusted the duration by moving the beginning or the end of the period and want the invoicing decrease/increase to reflect that - the default is invoicing the period with the amount specified in the campaign

  • "renewed" - (optional, can only be used on the first period given) set to true to register the period as one that was renewed with regards to invoice timing - this can be relevant when importing subscriptions that have already run for some time in another system, the default is false meaning that this is a new subscription

An example of creating a new subscription, with a single period on the given campaign:

[
  {
    "id": "12345", // customer ID
    "operation": "createsubscription",
    "periods": [ {
      "campaign_id": "3months"  // id of the campaign inside Iteras
    } ]
    "data": {
      ":Custom subscription field": "test value"
    }
  }
]

# Operation "updatesubscription"

Update the data on a subscription. Parameters:

  • "subscription_id" - ID of the subscription to assign the product to

  • "data" - any fields to set on the subscription - the valid fields are the ones associated with the products that the subscription is subscribed to

  • "reinvoice" - this can be set to true if the update changes the pricing of the subscription to make the change take effect immediately, the system will then credit the future part of the subscription (if it has been invoiced already) and set it up to be invoiced

An example:

[
  {
    "id": "12345",                   // customer ID
    "operation": "updatesubscription",
    "subscription_id": "32142532",
    "data": {
      ":Custom subscription field": "Some value",
      ":Obsolete field": null        // passing null deletes the field
    }
  }
]

# Operation "switchsubscriptionplan"

Switch a subscription over to a new campaign. Parameters:

  • "subscription_id" - ID of the subscription to switch plan for

  • "new_campaign_id" - ID of the campaign to switch to

  • "renewed" - (optional, very rarely useful) can be set to false in the specific case where you want the newly created period to be treated as if it was the first period of the subscription - e.g. inside Iteras you can set up the invoice timing machinery to advance or delay invoicing of the first period

The switch is done immediately. The ongoing period is stopped and a successor is created with the new campaign.

An example:

[
  {
    "id": "12345",                   // customer ID
    "operation": "switchsubscriptionplan",
    "subscription_id": "32142532",
    "new_campaign_id": "3months"
  }
]

# Operation "cancelsubscription"

Stop a subscription. Parameters:

  • "subscription_id" - ID of the subscription to switch plan for

  • "stop_at" - (optional, default now) when the subscription should stop, e.g. "2001-12-31T00:00:00"

The stop is done immediately, or in case stop_at extends out to a future period, as soon as possible. When stopping, there is usually an amount up until the given stop time which should still be paid, and an amount afterwards which may have already been invoiced. The latter is credited automatically by the stop.

An example:

[
  {
    "id": "12345",                   // customer ID
    "operation": "cancelsubscription",
    "subscription_id": "32142532",
    "stop_at": "2001-12-31T00:00:00"
  }
]

# Operation "assignproduct"

Assign a product to a customer/subscription.

There are two distinct kind of assignments you can make.

You can assign a recurring product to a subscription, to dynamically control what the subscription subscribes to instead of relying on the fixed choice in the campaign. By attaching data to the assignment, you can model unique product for each subscription. To make this kind of assignment, you need to fill in the subscription_id and target a product of the right kind.

The other kind of assignment is of individual products to one of the periods of the subscription by filling in subscription_id and period. In this case, the product must belong to the same category as what the subscription subscribes to.

You can also leave out subscription_id to assign an individual product directly to a customer, e.g. if signing up a customer to an event.

Parameters:

  • "subscription_id" - ID of the subscription to assign the product to

  • "period" - either "current" (default) or the index of the period, with the oldest period first, e.g. 1 for the first period

  • "name" or "external_id" - either name or the external ID of the product to assign

  • "data" (optional) - any attributes to attach to the product assignment, the valid attributes are the fields that are associated with the product

Example of assigning a recurring product:

[
  {
    "id": "12345",                   // customer ID
    "operation": "assignproduct",
    "subscription_id": "32142532",
    "name": "Recurring product",
    "data": {
      ":Custom product field": "Some value",
      ":Custom date field": "2001-12-31",
      ":Obsolete field": null        // passing null deletes the field
    }
  }
]

Example of assigning an individual product to a period, using external_id as key instead of the product name:

[
  {
    "id": "12345",                   // customer ID
    "operation": "assignproduct",
    "subscription_id": "32142532",
    "period": "current",
    "external_id": "may-issue"
  }
]

Example of assigning an event product directly to customer:

[
  {
    "id": "12345",                   // customer ID
    "operation": "assignproduct",
    "external_id": "the-great-conference"
  }
]

# Operation "updateproductassignment"

Update the data on a product assignment. Parameters:

  • "product_assignment_id" - ID of the assignment, as returned by the /api/customers/ endpoint

  • "data" - any attributes to set on the product assignment - the valid attributes are the fields that are associated with the product

  • "reinvoice" - for a product assignment that is associated with a subscription (and not a period) this can be set to true if the update changes the pricing of the subscription to make the change take effect immediately, the system will then credit the future part of the subscription (if it has been invoiced already) and set it up to be invoiced

An example:

[
  {
    "id": "12345",                   // customer ID
    "operation": "updateproductassignment",
    "product_assignment_id": "9989892798",
    "data": {
      ":Custom product field": "Another value",
      ":Obsolete field": null        // passing null deletes the field
    }
  }
]

# Operation "cancelproductassignment"

Cancel a previous assignment of a product to a subscription. Parameters:

  • "product_assignment_id" - ID of the assignment, as returned by the /api/customers/ endpoint

  • "credit_amount" (optional) - integer amount (send €10.50 as 1050) to credit while cancelling the product assignment, the amount can't exceed the amount invoiced when the product was assigned

An example:

[
  {
    "id": "12345",                   // customer ID
    "operation": "cancelproductassignment",
    "product_assignment_id": "9989892798",
    "credit_amount": 1050
  }
]

# Operation "begincommitmentperiod"

Start a new commitment period for a subscription. If one was already open, it will be ended automatically - more precisely have its end time moved to the beginning of the new commitment period. Iteras will register the commitment and calculate the future invoicing that the commitment entails. So if you have any invoicing adjustments, do them before beginning the commitment period, or they will not be included in the locked down commitment.

Parameters:

  • "subscription_id" - ID of the subscription where the commitment period holds for

  • "begin" (optional) - when the commitment starts, e.g. "2001-12-31T08:20:00", default is now - note, you can't backdate this (except for a small margin to account for request flight time) since commitment periods may be used in accounting

  • "end" - when the commitment ends, e.g. "2002-06-31T08:20:00"

An example:

[
  {
    "id": "12345",                   // customer ID
    "operation": "begincommitmentperiod",
    "subscription_id": "32142532",
    "end": "2002-06-31T08:20:00"
  }
]

# Operation "endcommitmentperiod"

Checks if there is an open commitment period on a subscription, and if so closes it. Parameters:

  • "subscription_id" - ID of the subscription where the commitment period holds for

  • "end" (optional) - when the commitment ends, e.g. "2002-06-31T08:20:00", default is now - note that you cannot backdate this, for the same as you cannot backdate the beginning of a commitment period

An example:

[
  {
    "id": "12345",                   // customer ID
    "operation": "endcommitmentperiod",
    "subscription_id": "32142532"
  }
]

# Operation "createpayment"

Create a payment on a customer. Parameters:

  • "invoice_number" (optional) - the specific invoice the payment should be allocated to - if you don't have an invoice number, you may need to specify the business entity if there are more than one

  • "business_entity_name" (optional) - name of the business entity inside Iteras to connect the payment to, if you do not specify an invoice and have more than one business entity

  • "amount" - integer amount (send €10.50 as 1050)

  • "currency" - three-letter ISO currency code, e.g. EUR, the currency must match the invoice/business entity

  • "method" (optional) - payment method, currently either manual (default, for manually registered), internal (internal transfer of funds) or external (for refunds registered on behalf of other system)

  • "note" (optional) - internal note attached to the payment

Examples:

[
  {
    "operation": "createpayment",
    "id": "12345",                   // customer ID
    "business_entity_name": "Publisher Ltd.",
    "amount": 1050,
    "currency": "DKK",
    "note": "Balance from old system"
  }
]
[
  {
    "operation": "createpayment",
    "id": "12345",                   // customer ID
    "invoice_number": 1007,
    "amount": 1050,
    "currency": "DKK"
  }
]

# Operation "invoice"

Invoice a number of invoice lines on a customer. Parameters:

  • "lines" - the lines to invoice as a list of objects with the following parameters:

    • "text" - description of what is invoiced, may contain newlines, e.g. Extra service\nLine 2

    • "amount" - integer amount (send €10.50 as 1050), including any tax

    • "currency" - three-letter ISO currency code, e.g. EUR, the currency must match the invoice/business entity

    • "tax_rate" - the tax rate applied to the line, e.g. 0.25 for 25% tax, set it to 0 for lines that are exempt from tax

  • "business_entity_name" (optional) - the business entity to invoice for, must be specified if subscription_id is not given

  • "subscription_id" (optional) - if the invoice lines concern a certain subscription

  • "period" (optional) - either "current" (default) or the index of the period, with 1 being the oldest period, in case a subscription_id is specified - note that invoice lines never bind to the subscription directly but always a specific period of the subscription

  • "due" (optional) - date the invoice is due, e.g. 2000-12-30, if not filled in, the due date is computed automatically

  • "send" (optional) - set this to false to prevent having the invoice be sent, this can be useful when importing old debt

  • "note" (optional) - internal note attached to the invoice

Examples:

[
  {
    "operation": "invoice",
    "id": "12345",                   // customer ID
    "lines": [{
      "text": "Product A",
      "amount": 10050,
      "currency": "DKK",
      "tax_rate": 0.25,
    }, {
      "text": "Shipping",
      "amount": 2050,
      "currency": "DKK",
      "tax_rate": 0,
    }],
    "subscription_id": "32142532",
    "due": "2001-02-28",
  }
]
[
  {
    "operation": "invoice",
    "id": "12345",                   // customer ID
    "lines": [{
      "text": "Unpaid amount from Jan-Feb",
      "amount": 56095,
      "currency": "DKK",
      "tax_rate": 0.25,
    }],
    "business_entity_name": "Publisher Ltd.",
    "due": "2001-02-28",
    "send": false,
    "note": "Balance from old system",
  }
]