Updating member dates, type, and chapter via business flows

Updating restricted Party properties via the iMIS REST API

Several PartyData.AdditionalAttributes values — JoinDate, PaidThruDate, RenewedThruDate, CustomerTypeCode, and Chapter — cannot be written through the /api/Party endpoint by an external, non-privileged caller. Attempts to set them through AdditionalAttributes return a validation error stating that updating those fields via the API requires staff or system administrator permissions. Same-value writes — where the supplied value matches the currently-persisted value — are short-circuited and never trigger the block, so round-trip GET → modify-other-fields → PUT calls are safe.

These fields can still be updated through their natural business flows: purchasing a dues subscription, assigning a chapter through group membership, or generating a renewal run. The end result on the party record is identical — the path is the one iMIS expects for these changes.

Subscription-based products cannot be added to a cart directly. They must be purchased through a billing cycle. The cart receives the purchase via a three-tier order-line structure. See Purchasing non-dues subscriptions for more information.

This guide lists each flow, the endpoints it uses, the request shapes you need, and the fields that change as a side effect.


Which property → which flow

PropertyRecommended flow
JoinDateJoin Now workflow (typically the iMIS Join Now iPart) or dues-import package — Flow 4
PaidThruDateSubscription purchase + invoice payment, renewal-run + invoice payment, or dues-import package — Flows 1, 3, 4
RenewedThruDateSubscription purchase, renewal run, or dues-import package — Flows 1, 3, 4
CustomerTypeCodeJoin Now workflow under a membership-based billing cycle (iMIS Join Now iPart)
ChapterGroup-membership add under a chapter group — Flow 2

Flow 1 — Adding and billing a subscription

Use this flow to add a subscription product to an existing party and bill them for it. This is the simpler of the two purchase-style flows — a single POST creates the subscription, advances its term, and creates an invoice in one call. The invoice can then be paid through any normal channel (the iMIS UI, a cart-payment iPart, or your own integration).

For full enrollment of a brand-new member where you also need JoinDate / CustomerTypeCode to be set automatically, see the iMIS Join Now workflow — that path runs through the cart with a three-tier order line into a membership-based billing cycle and is documented in Adding, modifying, and paying for a subscription and Purchasing non-dues subscriptions. It is out of scope here because the partner audience for that flow is typically the Join Now iPart, not a back-office integration.

Endpoints

EndpointMethodPurpose
/api/SubscriptionPOSTCreate a subscription with BillSubscription: true; returns the new InvoiceId
/api/InvoiceSummary/{InvoiceId}GETRead the resulting invoice
/api/ComboOrderPOSTPay the invoice by submitting a ComboOrder that references it

Step 1 — Create and bill the subscription

POST /api/Subscription
Content-Type: application/json

{
  "$type": "Asi.Soa.Commerce.DataContracts.SubscriptionData, Asi.Contracts",
  "PartyId": "12345",
  "ItemId": "REG",
  "BeginDate": "2026-01-01T00:00:00",
  "BillToPartyId": "12345",
  "BillSubscription": true
}

The response is 201 Created and includes the newly-created subscription. Capture:

  • InvoiceId — the invoice generated for the bill
  • BillBegin / BillThrough — the new term
  • BilledAmount — invoice total

Step 2 — Read the resulting invoice

GET /api/InvoiceSummary/{InvoiceId}

You'll send the full response back as part of the next step's Invoices collection.

Step 3 — Pay the invoice by submitting a ComboOrder

Submit a ComboOrderData that references the existing invoice. The Order itself has no lines — the work is the payment application against the invoice already on file. The response is 201 Created with the populated ComboOrder.

POST /api/ComboOrder
Content-Type: application/json

{
  "$type": "Asi.Soa.Commerce.DataContracts.ComboOrderData, Asi.Contracts",
  "Currency": { "$type": "Asi.Soa.Core.DataContracts.CurrencyData, Asi.Contracts", "CurrencyCode": "USD", "DecimalPositions": 2 },
  "Order": {
    "$type": "Asi.Soa.Commerce.DataContracts.OrderData, Asi.Contracts",
    "BillToCustomerParty":     { "$type": "Asi.Soa.Commerce.DataContracts.CustomerPartyData, Asi.Contracts", "PartyId": "12345" },
    "OriginatorCustomerParty": { "$type": "Asi.Soa.Commerce.DataContracts.CustomerPartyData, Asi.Contracts", "PartyId": "12345" },
    "SoldToCustomerParty":     { "$type": "Asi.Soa.Commerce.DataContracts.CustomerPartyData, Asi.Contracts", "PartyId": "12345" },
    "Currency":                { "$type": "Asi.Soa.Core.DataContracts.CurrencyData, Asi.Contracts", "CurrencyCode": "USD", "DecimalPositions": 2 },
    "Lines":                   { "$type": "Asi.Soa.Commerce.DataContracts.OrderLineDataCollection, Asi.Contracts", "$values": [] },
    "Delivery":                { "$type": "Asi.Soa.Commerce.DataContracts.DeliveryDataCollection, Asi.Contracts", "$values": [] }
  },
  "Invoices": {
    "$type": "Asi.Soa.Commerce.DataContracts.InvoiceSummaryDataCollection, Asi.Contracts",
    "$values": [ /* InvoiceSummaryData from step 2 */ ]
  },
  "Payments": {
    "$type": "Asi.Soa.Commerce.DataContracts.RemittanceDataCollection, Asi.Contracts",
    "$values": [
      {
        "$type": "Asi.Soa.Commerce.DataContracts.RemittanceData, Asi.Contracts",
        "Amount": {
          "$type": "Asi.Soa.Core.DataContracts.MonetaryAmountData, Asi.Contracts",
          "Amount": 95,
          "Currency": { "$type": "Asi.Soa.Core.DataContracts.CurrencyData, Asi.Contracts", "CurrencyCode": "USD", "DecimalPositions": 2 },
          "IsAmountDefined": true
        },
        "PaymentMethod":   { "$type": "Asi.Soa.Commerce.DataContracts.PaymentMethodData, Asi.Contracts", "PaymentMethodId": "CASH", "PaymentType": "Cash" },
        "PayorParty":      { "$type": "Asi.Soa.Commerce.DataContracts.CustomerPartyData, Asi.Contracts", "PartyId": "12345" },
        "ReferenceNumber": "12345"
      }
    ]
  }
}
📘

Notes:

  • Order.Lines is intentionally empty — there's nothing new being bought, you're paying for an invoice that already exists.
  • PaymentMethod only needs PaymentMethodId and PaymentType. The tenant's PaymentMethod record (for example, CASH → Main Checking Account) is resolved from those.
  • ReferenceNumber is intended for a check number or short payment reference.
  • For a cart-flavored workflow that buys a new item and pays at submit, see Adding, modifying, and paying for a subscription — that path > goes through POST /api/Cart + POST /api/Cart/_execute with a CartSubmissionRequest, not the simpler ComboOrder POST shown here.

Side effects on the party

When the subscription is created and billed (step 1):

  • The party gains a new Subscription row with BillBegin / BillThrough set to the new term.
  • An invoice is created for the billed amount.

When the invoice is paid (step 3 returns 201):

  • The invoice balance clears.
  • The corresponding subscription's PaidThru advances to its BillThrough.
  • For billable customer types (for example, M), the party's PaidThruDate advances to the subscription's BillThrough, and RenewedThruDate is updated by the renewal accounting. Non-billable customer types (staff, sysadmin, etc.) won't see these contact-level dates change — subscription-level dates still advance.
  • PaidThruDate and RenewedThruDate only update when the subscription is the contact's primary fee product for their customer type. A non-primary item (such as a journal or publication) advances its own subscription term but does not move the contact-level date fields.

Flow 2 — Assigning a chapter via group membership

Use this flow to set the party's chapter. Chapter is updated by creating a GroupMember under a group whose GroupId follows the chapter convention (CHAPT/<chapterCode>).

The update has two important rules:

  • On add, Chapter is set only if it is currently empty.
  • On remove, Chapter is cleared only if it currently matches the chapter being removed (so removing a non-current chapter membership is a no-op on this field).

Endpoints

EndpointMethodPurpose
/api/GroupMemberPOSTAdd the party to the chapter group
/api/GroupMember?EntityId={GroupMemberId}DELETERemove the party from the chapter group

Add a party to a chapter group

POST /api/GroupMember
Content-Type: application/json

{
  "$type": "Asi.Soa.Membership.DataContracts.GroupMemberData, Asi.Contracts",
  "Party": {
    "$type": "Asi.Soa.Membership.DataContracts.PartySummaryData, Asi.Contracts",
    "PartyId": "12345"
  },
  "Group": {
    "$type": "Asi.Soa.Membership.DataContracts.GroupSummaryData, Asi.Contracts",
    "GroupId": "CHAPT/EAST"
  },
  "JoinDate": "2026-01-01T00:00:00",
  "IsActive": true,
  "MembershipDetails": {
    "$type": "Asi.Soa.Membership.DataContracts.GroupMemberDetailDataCollection, Asi.Contracts",
    "$values": [
      {
        "$type": "Asi.Soa.Membership.DataContracts.GroupMemberDetailData, Asi.Contracts",
        "Role": {
          "$type": "Asi.Soa.Membership.DataContracts.GroupRoleData, Asi.Contracts",
          "RoleId": "SUBSCRIPTION:MEMBER"
        },
        "IsActive": true
      }
    ]
  }
}

The GroupMember schema is defined in Membership.json under #/definitions/GroupMemberData. Response is 201 Created; the returned GroupMemberId follows the format {GroupId}:{PartyId} (for example, CHAPT/EAST:12345).

Remove a party from a chapter group

The composite GroupMemberId contains both / and :, which the server's URL routing rejects when supplied as part of the path. Pass the identifier as the EntityId query parameter instead:

DELETE /api/GroupMember?EntityId=CHAPT/EAST:12345

Side effects on the party

  • Chapter ← the chapter code from the second segment of GroupId (for example, CHAPT/EASTEAST).
  • A corresponding chapter Subscription is created or updated as part of the same operation.

Flow 3 — Generating renewals

Use this flow to bill an existing member for the next term. This is the documented "Generating renewals" path (see Generating renewals) and is what updates RenewedThruDate and (after invoice payment) PaidThruDate for an existing member without going through the cart.

Endpoint

EndpointMethodPurpose
/api/LegacyBillingCycle/{LegacyBillingCycleId}GETLook up the billing cycle
/api/LegacyBilling/_executePOSTRunIndividual (single party) or Run (bulk)

Note: /api/LegacyBilling/_execute is referenced in the developer docs but is not currently published in the OpenAPI swagger. Treat the Generating renewals doc as the source of truth for its general request shape, with the parameter conventions below.

Request shape

/api/LegacyBilling/_execute accepts a GenericExecuteRequest whose Parameters is a positional Collection<object>, not a GenericPropertyDataCollection of named pairs. For RunIndividual the positions are:

  • [0] — the LegacyBillingData request object
  • [1] — the user/party id (string)
POST /api/LegacyBilling/_execute
Content-Type: application/json

{
  "$type": "Asi.Soa.Core.DataContracts.GenericExecuteRequest, Asi.Contracts",
  "EntityTypeName": "LegacyBilling",
  "OperationName": "RunIndividual",
  "Parameters": {
    "$type": "System.Collections.ObjectModel.Collection`1[[System.Object, mscorlib]], mscorlib",
    "$values": [
      {
        "$type": "Asi.Soa.Commerce.DataContracts.LegacyBillingData, Asi.Contracts",
        "IsRenewal": true,
        "RunDate": "2026-01-01T00:00:00",
        "EffectiveDate": "2026-01-01T00:00:00",
        "BillingCycleId": "Regular Membership Fees",
        "BillingRunName": "Renewal — 2026 — Party 12345"
      },
      "12345"
    ]
  }
}

Bulk renewal

Use "OperationName": "Run" with a single Parameters entry — only the LegacyBillingData object — to bill every party eligible for the cycle. Omit the second positional string.

Batch posting

When IndividualBillingPartyId (the trailing string parameter) is supplied, hot-posting behavior for the resulting accounting batch is controlled by the Membership setting "Do not require posting batch for single-member renewals". When that setting is enabled, the batch posts automatically as part of the call and no separate /api/BatchSummary/_execute Post step is required. If the setting is off and you still want automatic hot-posting for an individual run, set UseSelectedAccountingBatch: true on the LegacyBillingCycleData object passed in the request. Bulk runs always produce a batch that must be posted separately via BatchSummary.

Side effects on the party

Once the renewal run completes successfully:

  • RenewedThruDate ← the primary subscription's new bill-through date.
  • The party's Subscription rows have BillBegin / BillThrough advanced to the next term.
  • An invoice is created for the renewed-term balance.

After the invoice is paid:

  • PaidThruDate ← the subscription's bill-through date.

JoinDate is not changed by a renewal — it is set on the initial purchase.


Flow 4 — Dues-import package

Use this flow when you have an external system of record (legacy back office, third-party CRM, batch dues file) and need to apply per-party paid-through dates directly. The full request shape, async polling pattern (GetPackageStatus / GetPackageResults), batch handling, and validation rules are documented separately — this section only summarizes how the flow relates to the restricted Party properties.

See Importing billing and payment data for the full request bodies, field constraints, and status-enum values.

Endpoint

EndpointMethodPurpose
/api/DuesImportPackage/_executePOSTImportPackage, GetPackageStatus, GetPackageResults

Side effects on the party

Once a package finishes processing (status advances AwaitProcessingInProcessCompleted):

  • PaidThruDatePaidThruDate supplied on the import row.
  • RenewedThruDate ← bill-through date of the subscription created or extended by the import.
  • JoinDate ← set on first-time members based on the item's billing options.

Choosing a flow

GoalUse
Enroll a new member or sell an additional dues productFlow 1 (Add subscription, Retrieve invoice, Submit ComboOrder)
Assign or remove a chapter for a contactFlow 2 (GroupMember under a CHAPT/... group)
Bill an existing member's next term as part of a scheduled runFlow 3 (LegacyBilling)
Bulk-load paid-through dates from an external system of recordFlow 4 (DuesImportPackage)


Contact us
Copyright © Advanced Solutions International, All rights reserved.