API Reference

The djaodjin-saas API is split in four sections: Billing, Subscription, Metrics and Search.

The Billing and Subscription APIs deal with the actual business logic of a Software-as-a-Service, that is the transfer of funds and access control respectively.

The Metrics and Search APIs aggregate the underlying data in various ways to keep on top of the performance of the business as well as provide rich interfaces.

Billing API

These API end points manage the transfer of funds between a subscriber and a provider through a processor.

GET /api/billing/:organization/bank/
class saas.api.backend.RetrieveBankAPIView(**kwargs)

Pass through that calls the processor API to retrieve some details about the deposit account associated to a provider (if that information is available through the payment processor backend API).

This API does not trigger payment of a subscriber to a provider. Checkout of a subscription cart is done either through the HTML page or API end point.

  • balance_amount Amount available to transfer to the provider bank
  • balance_unit Unit of the available balance (ex: usd)
  • bank_name Name of the deposit account
  • last4 Last 4 characters of the deposit account identifier

Example response:

{
  "bank_name": "Stripe Test Bank",
  "last4": "***-htrTZ",
  "balance_amount": 0,
  "balance_unit": "usd"
}
GET /api/billing/:organization/billings/
class saas.api.transactions.BillingsAPIView(**kwargs)

GET queries all Transaction associated to :organization while the organization acts as a subscriber in the relation.

The queryset can be further filtered to a range of dates between start_at and ends_at.

The queryset can be further filtered by passing a q parameter. The value in q will be matched against:

  • Transaction.descr
  • Transaction.orig_organization.full_name
  • Transaction.dest_organization.full_name

The result queryset can be ordered by:

  • Transaction.created_at
  • Transaction.descr
  • Transaction.dest_amount

Example request:

GET /api/billing/xia/billings?start_at=2015-07-05T07:00:00.000Z&o=date&ot=desc

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "balance": 11000,
    "unit": "usd",
    "results": [
        {
            "created_at": "2015-08-01T00:00:00Z",
            "description": "Charge for 4 periods",
            "amount": "($356.00)",
            "is_debit": true,
            "orig_account": "Liability",
            "orig_organization": "xia",
            "orig_amount": 112120,
            "orig_unit": "usd",
            "dest_account": "Funds",
            "dest_organization": "stripe",
            "dest_amount": 112120,
            "dest_unit": "usd"
        }
    ]
}
GET /api/billing/:organization/card/
class saas.api.backend.RetrieveCardAPIView(**kwargs)

Pass through to the processor to retrieve some details about the payment method (ex: credit card) associated to a subscriber.

Example response:

{
  "last4": "1234",
  "exp_date": "12/2015"
}
DELETE /api/billing/:organization/balance/cancel/
class saas.api.transactions.CancelStatementBalanceAPIView(**kwargs)

Cancel the balance for a provider organization. This will create a transaction for this balance cancellation. A manager can use this endpoint to cancel balance dues that is known impossible to be recovered (e.g. an external bank or credit card company act).

The endpoint returns the transaction created to cancel the balance due.

Example request:

DELETE /api/billing/cowork/balance/
GET /api/billing/:organization/coupons/
POST /api/billing/:organization/coupons/
class saas.api.coupons.CouponListAPIView(**kwargs)

GET queries all Coupon associated to a provider.

The queryset can be further filtered by passing a q parameter. The value in q will be matched against:

  • Coupon.code
  • Coupon.description
  • Coupon.percent
  • Coupon.organization.full_name

The result queryset can be ordered by:

  • Coupon.code
  • Coupon.created_at
  • Coupon.description
  • Coupon.ends_at
  • Coupon.percent

Example request:

GET /api/billing/cowork/coupons?o=code&ot=asc&q=DIS

Example response:

{
    "count": 2,
    "next": null,
    "previous": null,
    "results": [
        {
            "code": "DIS100",
            "percent": 100,
            "created_at": "2014-01-01T09:00:00Z",
            "ends_at": null,
            "description": null
        },
        {
            "code": "DIS50",
            "percent": 50,
            "created_at": "2014-01-01T09:00:00Z",
            "ends_at": null,
            "description": null
        }
    ]
}

POST creates a Coupon (see /api/billing/:organization/coupons/:coupon/ for an example of JSON data).

GET /api/billing/:organization/coupons/:coupon/
PUT /api/billing/:organization/coupons/:coupon/
DELETE /api/billing/:organization/coupons/:coupon/
class saas.api.coupons.CouponDetailAPIView(**kwargs)

Retrieve, update or delete a Coupon.

Example response:

 {
     "code": "DIS100",
     "percent": 100,
     "created_at": "2014-01-01T09:00:00Z",
     "ends_at": null,
     "description": null
}
GET /api/billing/:organization/receivables/
class saas.api.transactions.ReceivablesListAPIView(**kwargs)

GET queries all receivables for a provider.

The queryset can be further filtered to a range of dates between start_at and ends_at.

The queryset can be further filtered by passing a q parameter. The value in q will be matched against:

  • Transaction.descr
  • Transaction.orig_organization.full_name
  • Transaction.dest_organization.full_name

The result queryset can be ordered by:

  • Transaction.created_at
  • Transaction.descr
  • Transaction.dest_amount

Example request:

GET /api/billing/cowork/receivables?start_at=2015-07-05T07:00:00.000Z&o=date&ot=desc

Example response:

{
    "count": 1,
    "total": "112120",
    "unit": "usd",
    "next": null,
    "previous": null,
    "results": [
        {
            "created_at": "2015-08-01T00:00:00Z",
            "description": "Charge <a href="/billing/cowork/receipt/1123">1123</a> distribution for demo562-open-plus",
            "amount": "112120",
            "is_debit": false,
            "orig_account": "Funds",
            "orig_organization": "stripe",
            "orig_amount": 112120,
            "orig_unit": "usd",
            "dest_account": "Funds",
            "dest_organization": "cowork",
            "dest_amount": 112120,
            "dest_unit": "usd"
        }
    ]
}
GET /api/billing/:organization/transfers/
class saas.api.transactions.TransferListAPIView(**kwargs)

GET queries all Transaction associated to :organization while the organization acts as a provider in the relation.

The queryset can be further filtered to a range of dates between start_at and ends_at.

The queryset can be further filtered by passing a q parameter. The value in q will be matched against:

  • Transaction.descr
  • Transaction.orig_organization.full_name
  • Transaction.dest_organization.full_name

The result queryset can be ordered by:

  • Transaction.created_at
  • Transaction.descr
  • Transaction.dest_amount

Example request:

GET /api/billing/cowork/transfers?start_at=2015-07-05T07:00:00.000Z&o=date&ot=desc

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created_at": "2015-08-01T00:00:00Z",
            "description": "Charge <a href="/billing/cowork/receipt/1123">1123</a> distribution for demo562-open-plus",
            "amount": "$1121.20",
            "is_debit": false,
            "orig_account": "Funds",
            "orig_organization": "stripe",
            "orig_amount": 112120,
            "orig_unit": "usd",
            "dest_account": "Funds",
            "dest_organization": "cowork",
            "dest_amount": 112120,
            "dest_unit": "usd"
        }
    ]
}
GET /api/billing/transactions/
class saas.api.transactions.TransactionListAPIView(**kwargs)

GET queries all Transaction recorded in the ledger.

The queryset can be further filtered to a range of dates between start_at and ends_at.

The queryset can be further filtered by passing a q parameter. The value in q will be matched against:

  • Transaction.descr
  • Transaction.orig_organization.full_name
  • Transaction.dest_organization.full_name

The result queryset can be ordered by:

  • Transaction.created_at
  • Transaction.descr
  • Transaction.dest_amount

Example request:

GET /api/billing/transactions?start_at=2015-07-05T07:00:00.000Z&o=date&ot=desc

Example response:

{
    "ends_at": "2017-03-30T18:10:12.962859Z",
    "balance": 11000,
    "unit": "usd",
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created_at": "2017-02-01T00:00:00Z",
            "description": "Charge for 4 periods",
            "amount": "($356.00)",
            "is_debit": true,
            "orig_account": "Liability",
            "orig_organization": "xia",
            "orig_amount": 112120,
            "orig_unit": "usd",
            "dest_account": "Funds",
            "dest_organization": "stripe",
            "dest_amount": 112120,
            "dest_unit": "usd"
        }
    ]
}
GET /api/billing/charges/
class saas.api.charges.ChargeListAPIView(**kwargs)

List of Charge.

Example request:

GET /api/charges?start_at=2015-07-05T07:00:00.000Z&o=date&ot=desc

Example response:

{
    "count": 1,
    "unit": "usd",
    "total": "112120",
    "next": null,
    "previous": null,
    "results": [{
        "created_at": "2016-01-01T00:00:00Z",
        "readable_amount": "$1121.20",
        "amount": 112120,
        "unit": "usd",
        "description": "Charge for subscription to cowork open-space",
        "last4": "1234",
        "exp_date"" "12/2016",
        "processor_key": "ch_XAb124EF",
        "state": "DONE"
    } ...]
GET /api/billing/charges/:charge/
class saas.api.charges.ChargeResourceView(**kwargs)

Pass through to the processor and returns details about a Charge.

Example response:

{
    "created_at": "2016-01-01T00:00:00Z",
    "readable_amount": "$1121.20",
    "amount": 112120,
    "unit": "usd",
    "description": "Charge for subscription to cowork open-space",
    "last4": "1234",
    "exp_date"" "12/2016",
    "processor_key": "ch_XAb124EF",
    "state": "DONE"
}
POST /api/billing/charges/:charge/email/
class saas.api.charges.EmailChargeReceiptAPIView(**kwargs)

Email the charge receipt to the customer email address on file.

Example response:

{
    "charge_id": "ch_XAb124EF",
    "email": "info@djaodjin.com"
}
POST /api/billing/charges/:charge/refund/
class saas.api.charges.ChargeRefundAPIView(**kwargs)

Partially or totally refund all or a subset of line items on a Charge.

Example request:

POST /api/billing/charges/ch_XAb124EF/refund/

{
    "lines": [
      {
          "num": 0,
          "refunded_amount": 4000,
      },
      {
          "num": 1,
          "refunded_amount": 82120,
      }
  ]
}

Example response:

{
    "created_at": "2016-01-01T00:00:00Z",
    "readable_amount": "$1121.20",
    "amount": 112120,
    "unit": "usd",
    "description": "Charge for subscription to cowork open-space",
    "last4": "1234",
    "exp_date"" "12/2016",
    "processor_key": "ch_XAb124EF",
    "state": "DONE"
}
POST /api/cart/
class saas.api.billing.CartItemAPIView(**kwargs)

Add a Plan into the subscription cart of the request.user.

The cart can later be checked out and paid by an Organization, either through the HTML page or API end point.

This end point is typically used when a user is presented with a list of add-ons that she can subscribes to in one checkout screen. The end-point works in both cases, authenticated or anonymous users. For authenticated users, the cart is stored in the database as CartItem objects. For anonymous users, the cart is stored in an HTTP Cookie.

The end-point accepts a single item or a list of items.

Example request:

POST /api/cart/

{
    "plan": "open-space",
    "quantity": 1
}

Example response:

{
    "plan": "open-space",
    "quantity": 1
}

quantity is optional. When it is not specified, subsquent checkout screens will provide choices to pay multiple periods in advance When additional first_name, last_name and sync_on are specified, payment can be made by one Organization for another Organization to be subscribed (see GroupBuy orders).

POST /api/cart/redeem/
class saas.api.coupons.CouponRedeemAPIView(**kwargs)

Redeem a Coupon and apply the discount to the eligible items in the cart.

Example request:

{
    "code": "LABORDAY"
}

Example response:

{
    "details": "Coupon 'LABORDAY' was successfully applied."
}
DELETE /api/cart/<plan>/
class saas.api.billing.CartItemDestroyAPIView(**kwargs)

Remove a Plan from the subscription cart of the request.user.

Example request:

DELETE /api/cart/:plan

Example response:

204 NO_CONTENT
DELETE /api/cart/:plan/upload/
class saas.api.billing.CartItemUploadAPIView(**kwargs)

Add a Plan into the subscription cart of multiple users as per the content of an uploaded file.

This works bulk fashion of /cart/ endpoint. The uploaded file must be a CSV containing the fields first_name, last_name and email. The CSV file must not contain a header line, only data.

Example request:

Content of names.csv:

POST /api/cart/:plan/upload/

Content-Disposition: form-data; name="file"; filename="names.csv"
Content-Type: text/csv

Example response:

{
    "created" [
        {
            "first_name": "Joe",
            "last_name": "Smith",
            "email": "joesmith@example.com"
        },
        {
            "first_name": "Marie",
            "last_name": "Johnson",
            "email": "mariejohnson@example.com"
        }
    ],
    "updated": [],
    "failed": []
}
POST /api/billing/:organization/checkout
class saas.api.billing.CheckoutAPIView(**kwargs)

Get the list of invoicables from a user cart, and checkout the cart of the request user on POST.

Example request:

GET /api/billing/:organization/checkout

Example response:

[{
  "subscription":{
      "created_at":"2016-06-21T23:24:09.242925Z",
      "ends_at":"2016-10-21T23:24:09.229768Z",
      "description":null,
      "organization":{
          "slug":"xia",
          "full_name":"Xia",
          "printable_name":"Xia",
          "created_at":"2012-08-14T23:16:55Z",
          "email":"xia@localhost.localdomain"
      },
      "plan":{
          "slug":"basic",
          "title":"Basic",
          "description":"Basic Plan",
          "is_active":true,
          "setup_amount":0,
          "period_amount":2000,
          "interval":4,
          "app_url":"/app/"
      },
      "auto_renew":true
  },
  "lines":[{
      "created_at":"2016-06-21T23:42:13.863739Z",
      "description":"Subscription to basic until 2016/11/21 (1 month)",
      "amount":"$20.00",
      "is_debit":false,
      "orig_account":"Receivable",
      "orig_organization":"cowork",
      "orig_amount":2000,
      "orig_unit":"usd",
      "dest_account":"Payable",
      "dest_organization":"xia",
      "dest_amount":2000,
      "dest_unit":"usd"
  }],
  "options":[]
}]

Example request:

POST /api/billing/:organization/checkout

{
    "remember_card": true,
    "processor_token": "token-from-payment-processor"
}

Example response:

{
     "created_at": "2016-06-21T23:42:44.270977Z",
     "processor_key": "pay_5lK5TacFH3gbKe"
     "amount": 2000,
     "unit": "usd",
     "description": "Charge pay_5lK5TacFH3gblP on credit card of Xia",
     "last4": "1234",
     "exp_date": "2016-06-01",
     "state": "created"
 }

Subscription API

These API end points manage the subscription logic, payments excluded.

POST /api/profile/:organization/plans/
class saas.api.plans.PlanCreateAPIView(**kwargs)

Create a Plan for a provider.

Example request:

POST /api/profile/cowork/plans

{
    "title": "Open Space",
    "description": "A desk in our coworking space",
    "is_active": false,
    "period_amount": 12000,
    "interval": 1
}

Example response:

{
    "title": "Open Space",
    "description": "A desk in our coworking space",
    "is_active": false,
    "period_amount": 12000,
    "interval": 1
}
GET /api/profile/:organization/plans/:plan/
PUT /api/profile/:organization/plans/:plan/
DELETE /api/profile/:organization/plans/:plan/
class saas.api.plans.PlanResourceView(**kwargs)

Retrieve, update or delete a Plan.

The is_active boolean is used to activate a plan, enabling users to subscribe to it, or deactivate a plan, disabling users from subscribing to it.

Example request:

GET /api/profile/cowork/plans/open-space

Example response:

{
    "title": "Open Space",
    "description": "A desk in our coworking space",
    "is_active": false,
    "period_amount": 12000,
    "interval": 1
}
GET /api/profile/:organization/plans/:plan/subscriptions/
POST /api/profile/:organization/plans/:plan/subscriptions/
class saas.api.subscriptions.PlanSubscriptionsAPIView(**kwargs)

A GET request will list all Subscription to a specified :plan provided by :organization.

A POST request will subscribe an organization to the :plan.

The value passed in the q parameter will be matched against:

  • Organization.slug
  • Organization.full_name
  • Organization.email
  • Organization.phone
  • Organization.street_address
  • Organization.locality
  • Organization.region
  • Organization.postal_code
  • Organization.country

The result queryset can be ordered by:

  • Organization.created_at
  • Organization.full_name

Example request:

GET /api/profile/:organization/plans/:plan/subscriptions/

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
        "slug": "xia",
        "full_name": "Xia Lee",
        "created_at": "2016-01-14T23:16:55Z"
        }
    ]
}

Example request:

POST /api/profile/:organization/plans/:plan/subscriptions/

{
  "organizatoin": {
    "slug": "xia"
  }
}

Example response:

201 CREATED
{
  "created_at": "2016-01-14T23:16:55Z",
  "ends_at": "2017-01-14T23:16:55Z",
  "description": null,
  "organization": {
    "slug": "xia",
    "printable_name": "Xia Lee"
  },
  "plan": {
    "slug": "open-space",
    "title": "Open Space",
    "description": "open space desk, High speed internet
                      - Ethernet or WiFi, Unlimited printing,
                        Unlimited scanning, Unlimited fax service
                        (send and receive)",
    "is_active": true,
    "setup_amount": 0,
    "period_amount": 17999,
    "interval": 4,
    "app_url": "http://localhost:8020/app"
  },
  "auto_renew": true
}
GET /api/profile/:organization/
PUT /api/profile/:organization/
DELETE /api/profile/:organization/
class saas.api.organizations.OrganizationDetailAPIView(**kwargs)

Retrieve, update or delete an Organization.

Example response:

{
    "slug": "xia",
    "full_name": "Xia Lee",
    "created_at": "2016-01-14T23:16:55Z",
    "subscriptions": [
        {
            "created_at": "2016-01-14T23:16:55Z",
            "ends_at": "2017-01-14T23:16:55Z",
            "plan": "open-space",
            "auto_renew": true
        }
    ]
}

On DELETE, we anonymize the organization instead of purely deleting it from the database because we don’t want to loose history on subscriptions and transactions.

GET /api/users/:user/accessibles/
POST /api/users/:user/accessibles/
class saas.api.roles.AccessibleByListAPIView(**kwargs)

GET lists all relations where an Organization is accessible by a User. Typically the user was granted specific permissions through a Role.

POST Generates a request to attach a user to a role on an organization

see Flexible Security Framework.

Example request:

GET  /api/users/alice/accessibles/

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created_at": "2012-10-01T09:00:00Z",
            "slug": "cowork",
            "printable_name": "ABC Corp.",
            "role_description": "manager",
            "request_key": null,
            "grant_key": null
        }
    ]
}

Example request:

POST /api/users/xia/accessibles/

{
  "slug": "cowork"
}

Example response:

{
  "slug": "cowork"
}
DELETE /api/users/:user/accessibles/:organization/
class saas.api.roles.RoleDetailAPIView(**kwargs)

Dettach a user from one or all roles with regards to an organization, typically resulting in revoking permissions from this user to manage part of an organization profile.

GET /api/profile/:organization/roles/describe/
POST /api/profile/:organization/roles/describe/
class saas.api.roles.RoleDescriptionListCreateView(**kwargs)

List and create RoleDescription.

see Flexible Security Framework.

Example request:

GET  /api/profile/cowork/roles/describe/

Example response:

{
    "count": 2,
    "next": null,
    "previous": null,
    "results": [
        {
            "created_at": "2016-01-14T23:16:55Z",
            "name": "Managers",
            "slug": "manager",
            "is_global": true,
            "roles": [
                {
                    "created_at": "2016-09-14T23:16:55Z",
                    "user": {
                        "slug": "donny",
                        "email": "support@djaodjin.com",
                        "full_name": "Donny Cooper",
                        "created_at": "2016-09-15T00:00:00Z"
                    },
                    "request_key": null,
                    "grant_key": null
                },
            ]
        },
        {
            "created_at": "2012-09-14T23:16:55Z",
            "name": "Contributors",
            "slug": "contributor",
            "is_global": true,
            "roles": []
        }
    ]
}
GET /api/profile/:organization/roles/describe/:role/
PUT /api/profile/:organization/roles/describe/:role/
DELETE /api/profile/:organization/roles/describe/:role/
class saas.api.roles.RoleDescriptionDetailView(**kwargs)

Create, retrieve, update and delete RoleDescription.

see Flexible Security Framework.

Example request:

GET  /api/profile/cowork/roles/describe/manager

Example response:

{
    "created_at": "2016-01-14T23:16:55Z",
    "name": "Managers",
    "slug": "manager",
    "is_global": true,
    "roles": [
        {
            "created_at": "2016-09-14T23:16:55Z",
            "user": {
                "slug": "donny",
                "email": "support@djaodjin.com",
                "full_name": "Donny Cooper",
                "created_at": "2016-09-15T00:00:00Z"
            },
            "request_key": null,
            "grant_key": null
        },
    ]
}
GET /api/profile/:organization/roles/:role/
POST /api/profile/:organization/roles/:role/
class saas.api.roles.RoleListAPIView(**kwargs)

GET lists all roles for an organization

Example request:

GET /api/profile/cowork/roles/

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created_at": "2012-10-01T09:00:00Z",
            "role_description": {
                "name": "Manager",
                "slug": "manager",
                "organization": {
                    "slug": "cowork",
                    "full_name": "ABC Corp.",
                    "printable_name": "ABC Corp.",
                    "created_at": "2012-08-14T23:16:55Z",
                    "email": "support@localhost.localdomain"
                }
            },
            "user": {
                "slug": "alice",
                "email": "alice@localhost.localdomain",
                "full_name": "Alice Doe",
                "created_at": "2012-09-14T23:16:55Z"
            },
            "request_key": "1",
            "grant_key": null
        },
    ]
}
DELETE /api/profile/:organization/roles/:role/:user/
class saas.api.roles.RoleDetailAPIView(**kwargs)

Dettach a user from one or all roles with regards to an organization, typically resulting in revoking permissions from this user to manage part of an organization profile.

GET /api/profile/:organization/subscribers/
class saas.api.organizations.SubscribersAPIView(**kwargs)

List all Organization which have or had a subscription to a plan provided by :organization.

The value passed in the q parameter will be matched against:

  • Organization.slug
  • Organization.full_name
  • Organization.email
  • Organization.phone
  • Organization.street_address
  • Organization.locality
  • Organization.region
  • Organization.postal_code
  • Organization.country

The result queryset can be ordered by:

  • Organization.created_at
  • Organization.full_name

Example request:

GET /api/profile/:organization/subscribers/?o=created_at&ot=desc

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
        "slug": "xia",
        "full_name": "Xia Lee",
        "created_at": "2016-01-14T23:16:55Z"
        }
    ]
}
GET /api/profile/:organization/subscriptions/
POST /api/profile/:organization/subscriptions/
class saas.api.subscriptions.SubscriptionListAPIView(**kwargs)

GET queries all Subscription of an Organization. The queryset can be further refined to match a search filter (q) and sorted on a specific field. The returned queryset is always paginated.

The value passed in the q parameter will be matched against:

  • Subscription.organization.slug
  • Subscription.organization.full_name
  • Subscription.organization.email
  • Subscription.organization.phone
  • Subscription.organization.street_address
  • Subscription.organization.locality
  • Subscription.organization.region
  • Subscription.organization.postal_code
  • Subscription.organization.country
  • Subscription.plan.title

The result queryset can be ordered by:

  • Subscription.created_at
  • Subscription.ends_at
  • Subscription.organization.full_name
  • Subscription.plan.title

Example request:

GET /api/profile/:organization/subscriptions/?o=created_at&ot=desc

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created_at": "2016-01-14T23:16:55Z",
            "ends_at": "2017-01-14T23:16:55Z",
            "description": null,
            "organization": {
                "slug": "xia",
                "printable_name": "Xia Lee"
            },
            "plan": {
                "slug": "open-space",
                "title": "Open Space",
                "description": "open space desk, High speed internet
                              - Ethernet or WiFi, Unlimited printing,
                              Unlimited scanning, Unlimited fax service
                              (send and receive)",
                "is_active": true,
                "setup_amount": 0,
                "period_amount": 17999,
                "interval": 4,
                "app_url": "http://localhost:8020/app"
            },
            "auto_renew": true
        }
    ]
}

POST subscribes the organization to a plan.

DELETE /api/profile/:organization/subscriptions/<subscribed_plan>/
class saas.api.subscriptions.SubscriptionDetailAPIView(**kwargs)

Unsubscribe an organization from a plan.

Metrics API

GET /api/metrics/registered/
class saas.api.users.RegisteredAPIView(**kwargs)

GET queries all User which have no associated role or a role to an Organization which has no Subscription, active or inactive.

The queryset can be further filtered to a range of dates between start_at and ends_at.

The queryset can be further filtered by passing a q parameter. The value in q will be matched against:

  • User.first_name
  • User.last_name
  • User.email

The result queryset can be ordered by:

  • User.first_name
  • User.last_name
  • User.email
  • User.created_at

Example request:

GET /api/metrics/registered?o=created_at&ot=desc

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "slug": "alice",
            "email": "alice@djaodjin.com",
            "full_name": "Alice Cooper",
            "created_at": "2014-01-01T00:00:00Z"
        }
    ]
}
GET /api/metrics/:organization/active/
class saas.api.subscriptions.ActiveSubscriptionAPIView(**kwargs)

GET queries all Subscription to a plan whose provider is :organization which are currently in progress.

The queryset can be further filtered to a range of dates between start_at and ends_at.

The queryset can be further filtered by passing a q parameter. The value in q will be matched against:

  • Subscription.organization.slug
  • Subscription.organization.full_name
  • Subscription.organization.email
  • Subscription.organization.phone
  • Subscription.organization.street_address
  • Subscription.organization.locality
  • Subscription.organization.region
  • Subscription.organization.postal_code
  • Subscription.organization.country
  • Subscription.plan.title

The result queryset can be ordered by:

  • Subscription.created_at
  • Subscription.ends_at
  • Subscription.organization.full_name
  • Subscription.plan.title

Example request:

GET /api/metrics/cowork/active?o=created_at&ot=desc

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created_at": "2016-01-14T23:16:55Z",
            "ends_at": "2017-01-14T23:16:55Z",
            "description": null,
            "organization": {
                "slug": "xia",
                "printable_name": "Xia Lee"
            },
            "plan": {
                "slug": "open-space",
                "title": "Open Space",
                "description": "open space desk, High speed internet
                            - Ethernet or WiFi, Unlimited printing,
                            Unlimited scanning, Unlimited fax service
                            (send and receive)",
                "is_active": true,
                "setup_amount": 0,
                "period_amount": 17999,
                "interval": 4,
                "app_url": "http://localhost:8020/app"
            },
            "auto_renew": true
        }
    ]
}
GET /api/metrics/:organization/balances/
class saas.api.metrics.BalancesAPIView(**kwargs)

Generate a table of revenue (rows) per months (columns).

Example request:

GET /api/metrics/cowork/balances

Example response:

{
    "title": "Balances",
    "scale": 0.01,
    "unit": "$",
    "table": [
        {
            "key": "Income",
            "values": [
                ["2014-09-01T00:00:00Z", 0],
                ["2014-10-01T00:00:00Z", 1532624],
                ["2014-11-01T00:00:00Z", 2348340],
                ["2014-12-01T00:00:00Z", 3244770],
                ["2015-01-01T00:00:00Z", 5494221],
                ["2015-02-01T00:00:00Z", 7214221],
                ["2015-03-01T00:00:00Z", 8444221],
                ["2015-04-01T00:00:00Z", 9784221],
                ["2015-05-01T00:00:00Z", 12784221],
                ["2015-06-01T00:00:00Z", 14562341],
                ["2015-07-01T00:00:00Z", 16567341],
                ["2015-08-01T00:00:00Z", 17893214],
                ["2015-08-06T02:24:50.485Z", 221340]
            ],
        },
        {
            "key": "Backlog",
            "values": [
                ["2014-09-01T00:00:00Z", 1712624],
                ["2014-10-01T00:00:00Z", 3698340],
                ["2014-11-01T00:00:00Z", 7214770],
                ["2014-12-01T00:00:00Z", 10494221],
                ["2015-01-01T00:00:00Z", 14281970],
                ["2015-02-01T00:00:00Z", 18762845],
                ["2015-03-01T00:00:00Z", 24258765],
                ["2015-04-01T00:00:00Z", 31937741],
                ["2015-05-01T00:00:00Z", 43002401],
                ["2015-06-01T00:00:00Z", 53331444],
                ["2015-07-01T00:00:00Z", 64775621],
                ["2015-08-01T00:00:00Z", 75050033],
                ["2015-08-06T02:24:50.485Z", 89156321]
            ],
        },
        {
            "key": "Receivable",
            "values": [
                ["2014-09-01T00:00:00Z", 0],
                ["2014-10-01T00:00:00Z", 0],
                ["2014-11-01T00:00:00Z", 0],
                ["2014-12-01T00:00:00Z", 0],
                ["2015-01-01T00:00:00Z", 0],
                ["2015-02-01T00:00:00Z", 0],
                ["2015-03-01T00:00:00Z", 0],
                ["2015-04-01T00:00:00Z", 0],
                ["2015-05-01T00:00:00Z", 0],
                ["2015-06-01T00:00:00Z", 0],
                ["2015-07-01T00:00:00Z", 0],
                ["2015-08-01T00:00:00Z", 0],
                ["2015-08-06T02:24:50.485Z", 0]
            ],
        }
    ]
}
GET /api/metrics/balances/:report/
class saas.api.balances.BrokerBalancesAPIView(**kwargs)

GET queries a balance sheet named :report for the broker.

Example request:

GET /api/metrics/balances/taxes/

Example response:

{
    "scale": 0.01,
    "unit": "$",
    "title": "Balances: taxes",
    "table": [
        {
            "key": "Sales",
            "selector": "Receivable",
            "values": [
                ["2015-05-01T00:00:00Z", 0],
                ["2015-08-01T00:00:00Z", 0],
                ["2015-11-01T00:00:00Z", 0],
                ["2016-02-01T00:00:00Z", 0],
                ["2016-05-01T00:00:00Z", 0],
                ["2016-05-16T21:08:15.637Z", 0]
            ]
        }
    ]
}
GET /api/metrics/lines/:report/
POST /api/metrics/lines/:report/
class saas.api.balances.BalanceLineListAPIView(**kwargs)

GET queries the list of rows reported on the balance sheet named :report for the broker.

POST adds a new row on the :report balance sheet.

Example request:

GET /api/metrics/lines/taxes/

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "title": "Sales",
            "selector": "Receivable",
            "rank": 1
        }
    ]
}

Example request:

POST /api/metrics/lines/taxes/

{
  "title": "Sales",
  "selector": "Receivable",
  "rank": 1
}

Example response:

{
  "title": "Sales",
  "selector": "Receivable",
  "rank": 1
}
GET /api/metrics/:organization/churned/
class saas.api.subscriptions.ChurnedSubscriptionAPIView(**kwargs)

GET queries all Subscription to a plan whose provider is :organization which have ended already.

The queryset can be further filtered to a range of dates between start_at and ends_at.

The queryset can be further filtered by passing a q parameter. The value in q will be matched against:

  • Subscription.organization.slug
  • Subscription.organization.full_name
  • Subscription.organization.email
  • Subscription.organization.phone
  • Subscription.organization.street_address
  • Subscription.organization.locality
  • Subscription.organization.region
  • Subscription.organization.postal_code
  • Subscription.organization.country
  • Subscription.plan.title

The result queryset can be ordered by:

  • Subscription.created_at
  • Subscription.ends_at
  • Subscription.organization.full_name
  • Subscription.plan.title

Example request:

GET /api/metrics/cowork/churned?o=created_at&ot=desc

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created_at": "2016-01-14T23:16:55Z",
            "ends_at": "2017-01-14T23:16:55Z",
            "description": null,
            "organization": {
                "slug": "xia",
                "printable_name": "Xia Lee"
            },
            "plan": {
                "slug": "open-space",
                "title": "Open Space",
                "description": "open space desk, High speed internet
                            - Ethernet or WiFi, Unlimited printing,
                            Unlimited scanning, Unlimited fax service
                            (send and receive)",
                "is_active": true,
                "setup_amount": 0,
                "period_amount": 17999,
                "interval": 4,
                "app_url": "http://localhost:8020/app"
            },
            "auto_renew": true
        }
    ]
}
GET /api/metrics/:organization/coupons/:coupon/
class saas.api.metrics.CouponUsesAPIView(**kwargs)

GET list uses of a Coupon.

class CartItemSmartListMixin

The queryset can be further filtered to a range of dates between start_at and ends_at.

The queryset can be further filtered by passing a q parameter. The value in q will be matched against:

  • user.username
  • user.first_name
  • user.last_name
  • user.email

The result queryset can be ordered by passing an o (field name) and ot (asc or desc) parameter. The fields the queryset can be ordered by are:

  • user.first_name
  • user.last_name
  • created_at

Example request:

GET /api/metrics/cowork/coupons/DIS100/

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "user": {
                "slug": "xia",
                "email": "xia@localhost.localdomain",
                "full_name": "Xia Doe",
                "created_at": "2012-09-14T23:16:55Z"
            },
            "plan": "basic",
            "created_at": "2014-01-01T09:00:00Z"
        }
    ]
}
GET /api/metrics/:organization/customers/
class saas.api.metrics.CustomerMetricAPIView(**kwargs)

Produce revenue stats

Example request:

GET /api/metrics/cowork/customers

Example response:

{
    "title": "Customers"
    "table": [
        {
            "key": "Total # of Customers",
            "values": [
                ["2014-10-01T00:00:00Z", 15],
                ["2014-11-01T00:00:00Z", 17],
                ["2014-12-01T00:00:00Z", 19],
                ["2015-01-01T00:00:00Z", 19],
                ["2015-02-01T00:00:00Z", 25],
                ["2015-03-01T00:00:00Z", 29],
                ["2015-04-01T00:00:00Z", 37],
                ["2015-05-01T00:00:00Z", 43],
                ["2015-06-01T00:00:00Z", 46],
                ["2015-07-01T00:00:00Z", 48],
                ["2015-08-01T00:00:00Z", 54],
                ["2015-08-06T05:20:24.537Z", 60]
            ]
        },
        {
            "key": "# of new Customers"
            "values": [
                ["2014-10-01T00:00:00Z", 2],
                ["2014-11-01T00:00:00Z", 2],
                ["2014-12-01T00:00:00Z", 0],
                ["2015-01-01T00:00:00Z", 6],
                ["2015-02-01T00:00:00Z", 4],
                ["2015-03-01T00:00:00Z", 8],
                ["2015-04-01T00:00:00Z", 6],
                ["2015-05-01T00:00:00Z", 3],
                ["2015-06-01T00:00:00Z", 2],
                ["2015-07-01T00:00:00Z", 6],
                ["2015-08-01T00:00:00Z", 7],
                ["2015-08-06T05:20:24.537Z", 0]
            ]
        },
        {
            "key": "# of churned Customers"
            "values": [
                ["2014-10-01T00:00:00Z", 0],
                ["2014-11-01T00:00:00Z", 0],
                ["2014-12-01T00:00:00Z", 0],
                ["2015-01-01T00:00:00Z", 0],
                ["2015-02-01T00:00:00Z", 0],
                ["2015-03-01T00:00:00Z", 0],
                ["2015-04-01T00:00:00Z", 0],
                ["2015-05-01T00:00:00Z", 0],
                ["2015-06-01T00:00:00Z", 0],
                ["2015-07-01T00:00:00Z", 0],
                ["2015-08-01T00:00:00Z", 1],
                ["2015-08-06T05:20:24.537Z", 60]
            ]
        },
        {
            "key": "Net New Customers",
            "values": [
                ["2014-10-01T00:00:00Z", 2],
                ["2014-11-01T00:00:00Z", 2],
                ["2014-12-01T00:00:00Z", 0],
                ["2015-01-01T00:00:00Z", 6],
                ["2015-02-01T00:00:00Z", 4],
                ["2015-03-01T00:00:00Z", 8],
                ["2015-04-01T00:00:00Z", 6],
                ["2015-05-01T00:00:00Z", 3],
                ["2015-06-01T00:00:00Z", 2],
                ["2015-07-01T00:00:00Z", 6],
                ["2015-08-01T00:00:00Z", 6],
                ["2015-08-06T05:20:24.537Z", -60]
            ]
        }
    ],
    "extra": [
        {
            "key": "% Customer Churn",
            "values": [
                ["2014-10-01T00:00:00Z", 0],
                ["2014-11-01T00:00:00Z", 0.0],
                ["2014-12-01T00:00:00Z", 0.0],
                ["2015-01-01T00:00:00Z", 0.0],
                ["2015-02-01T00:00:00Z", 0.0],
                ["2015-03-01T00:00:00Z", 0.0],
                ["2015-04-01T00:00:00Z", 0.0],
                ["2015-05-01T00:00:00Z", 0.0],
                ["2015-06-01T00:00:00Z", 0.0],
                ["2015-07-01T00:00:00Z", 0.0],
                ["2015-08-01T00:00:00Z", 2.08],
                ["2015-08-06T05:20:24.537Z", 111.11]
            ]
        }
    ]
}
GET /api/metrics/:organization/funds/
class saas.api.metrics.RevenueMetricAPIView(**kwargs)

Produce The sales, payments and refunds over a period of time.

Example request:

GET /api/metrics/cowork/revenue

Example response:

{
    "title": "Amount",
    "scale": 0.01,
    "unit": "$",
    "table": [
        {
            "key": "Total Sales",
            "values": [
                ["2014-10-01T00:00:00Z", 1985716],
                ["2014-11-01T00:00:00Z", 3516430],
                ["2014-12-01T00:00:00Z", 3279451],
                ["2015-01-01T00:00:00Z", 3787749],
                ["2015-02-01T00:00:00Z", 4480875],
                ["2015-03-01T00:00:00Z", 5495920],
                ["2015-04-01T00:00:00Z", 7678976],
                ["2015-05-01T00:00:00Z", 11064660],
                ["2015-06-01T00:00:00Z", 10329043],
                ["2015-07-01T00:00:00Z", 11444177],
                ["2015-08-01T00:00:00Z", 10274412],
                ["2015-08-06T04:59:14.721Z", 14106288]
            ]
        },
        {
            "key": "New Sales",
            "values": [
                ["2014-10-01T00:00:00Z", 0],
                ["2014-11-01T00:00:00Z", 0],
                ["2014-12-01T00:00:00Z", 0],
                ["2015-01-01T00:00:00Z", 0],
                ["2015-02-01T00:00:00Z", 0],
                ["2015-03-01T00:00:00Z", 0],
                ["2015-04-01T00:00:00Z", 0],
                ["2015-05-01T00:00:00Z", 0],
                ["2015-06-01T00:00:00Z", 0],
                ["2015-07-01T00:00:00Z", 0],
                ["2015-08-01T00:00:00Z", 0],
                ["2015-08-06T04:59:14.721Z", 0]
            ]
        },
        {
            "key": "Churned Sales",
            "values": [
                ["2014-10-01T00:00:00Z", 0],
                ["2014-11-01T00:00:00Z", 0],
                ["2014-12-01T00:00:00Z", 0],
                ["2015-01-01T00:00:00Z", 0],
                ["2015-02-01T00:00:00Z", 0],
                ["2015-03-01T00:00:00Z", 0],
                ["2015-04-01T00:00:00Z", 0],
                ["2015-05-01T00:00:00Z", 0],
                ["2015-06-01T00:00:00Z", 0],
                ["2015-07-01T00:00:00Z", 0],
                ["2015-08-01T00:00:00Z", 0],
                ["2015-08-06T04:59:14.721Z", 0]
            ]
        },
        {
            "key": "Payments",
            "values": [
                ["2014-10-01T00:00:00Z", 1787144],
                ["2014-11-01T00:00:00Z", 3164787],
                ["2014-12-01T00:00:00Z", 2951505],
                ["2015-01-01T00:00:00Z", 3408974],
                ["2015-02-01T00:00:00Z", 4032787],
                ["2015-03-01T00:00:00Z", 4946328],
                ["2015-04-01T00:00:00Z", 6911079],
                ["2015-05-01T00:00:00Z", 9958194],
                ["2015-06-01T00:00:00Z", 9296138],
                ["2015-07-01T00:00:00Z", 10299759],
                ["2015-08-01T00:00:00Z", 9246970],
                ["2015-08-06T04:59:14.721Z", 12695659]
            ]
        },
        {
            "key": "Refunds",
            "values": [
                ["2014-10-01T00:00:00Z", 0],
                ["2014-11-01T00:00:00Z", 0],
                ["2014-12-01T00:00:00Z", 0],
                ["2015-01-01T00:00:00Z", 0],
                ["2015-02-01T00:00:00Z", 0],
                ["2015-03-01T00:00:00Z", 0],
                ["2015-04-01T00:00:00Z", 0],
                ["2015-05-01T00:00:00Z", 0],
                ["2015-06-01T00:00:00Z", 0],
                ["2015-07-01T00:00:00Z", 0],
                ["2015-08-01T00:00:00Z", 0],
                ["2015-08-06T04:59:14.721Z", 0]
            ]
        }
    ],
}
GET /api/metrics/:organization/plans/
class saas.api.metrics.PlanMetricAPIView(**kwargs)

Produce plan stats

Example request:

GET /api/metrics/cowork/revenue

Example response:

{
    "title": "Active Subscribers",
    "table": [
        {
            "is_active": true,
            "key": "open-space",
            "location": "/profile/plan/open-space/",
            "values": [
                ["2014-09-01T00:00:00Z", 4],
                ["2014-10-01T00:00:00Z", 5],
                ["2014-11-01T00:00:00Z", 6],
                ["2014-12-01T00:00:00Z", 6],
                ["2015-01-01T00:00:00Z", 6],
                ["2015-02-01T00:00:00Z", 9],
                ["2015-03-01T00:00:00Z", 9],
                ["2015-04-01T00:00:00Z", 9],
                ["2015-05-01T00:00:00Z", 11],
                ["2015-06-01T00:00:00Z", 11],
                ["2015-07-01T00:00:00Z", 14],
                ["2015-08-01T00:00:00Z", 16],
                ["2015-08-06T05:37:50.004Z", 16]
            ]
        },
        {
            "is_active": true,
            "key": "open-plus",
            "location": "/profile/plan/open-plus/",
            "values": [
                ["2014-09-01T00:00:00Z", 7],
                ["2014-10-01T00:00:00Z", 8],
                ["2014-11-01T00:00:00Z", 9],
                ["2014-12-01T00:00:00Z", 9],
                ["2015-01-01T00:00:00Z", 12],
                ["2015-02-01T00:00:00Z", 13],
                ["2015-03-01T00:00:00Z", 18],
                ["2015-04-01T00:00:00Z", 19],
                ["2015-05-01T00:00:00Z", 19],
                ["2015-06-01T00:00:00Z", 20],
                ["2015-07-01T00:00:00Z", 23],
                ["2015-08-01T00:00:00Z", 25],
                ["2015-08-06T05:37:50.014Z", 25]
            ]
        },
        {
            "is_active": true,
            "key": "private",
            "location": "/profile/plan/private/",
            "values": [
                ["2014-09-01T00:00:00Z", 3],
                ["2014-10-01T00:00:00Z", 3],
                ["2014-11-01T00:00:00Z", 3],
                ["2014-12-01T00:00:00Z", 3],
                ["2015-01-01T00:00:00Z", 6],
                ["2015-02-01T00:00:00Z", 7],
                ["2015-03-01T00:00:00Z", 10],
                ["2015-04-01T00:00:00Z", 15],
                ["2015-05-01T00:00:00Z", 16],
                ["2015-06-01T00:00:00Z", 17],
                ["2015-07-01T00:00:00Z", 17],
                ["2015-08-01T00:00:00Z", 18],
                ["2015-08-06T05:37:50.023Z", 18]
            ]
        }
    ],
    "extra": [
        {
            "key": "churn",
            "values": [
                ["2014-09-01T00:00:00Z", 0],
                ["2014-10-01T00:00:00Z", 0],
                ["2014-11-01T00:00:00Z", 0],
                ["2014-12-01T00:00:00Z", 0],
                ["2015-01-01T00:00:00Z", 0],
                ["2015-02-01T00:00:00Z", 0],
                ["2015-03-01T00:00:00Z", 0],
                ["2015-04-01T00:00:00Z", 0],
                ["2015-05-01T00:00:00Z", 0],
                ["2015-06-01T00:00:00Z", 0],
                ["2015-07-01T00:00:00Z", 0],
                ["2015-08-01T00:00:00Z", 1],
                ["2015-08-06T05:37:50.031Z", 1]
            ]
        }
    ]
}

Search API

At times, we might be looking to grant a User permissions to an Organization through a Role (manager, etc.), or we might be looking to request access to an Organization on behalf of a User. Both features might benefit from an auto-complete suggestions list. The two following API end point will list all Organization and User in the database regardless of their associations.

class saas.api.organizations.OrganizationListAPIView(**kwargs)

GET queries all Organization.

class OrganizationSmartListMixin

The queryset can be further filtered to a range of dates between start_at and ends_at.

The queryset can be further filtered by passing a q parameter. The value in q will be matched against:

  • slug
  • full_name
  • email
  • phone
  • street_address
  • locality
  • region
  • postal_code
  • country

The result queryset can be ordered by passing an o (field name) and ot (asc or desc) parameter. The fields the queryset can be ordered by are:

  • full_name
  • created_at

Example request:

GET /api/profile/?o=created_at&ot=desc

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [{
        "slug": "xia",
        "full_name": "Xia Lee",
        "printable_name": "Xia Lee",
        "created_at": "2016-01-14T23:16:55Z"
    }]
}
class saas.api.users.UserListAPIView(**kwargs)

GET queries all User.

class UserSmartListMixin

User list which is also searchable and sortable.

The queryset can be further filtered to a before date with ends_at.

The queryset can be further filtered by passing a q parameter. The value in q will be matched against:

  • User.first_name
  • User.last_name
  • User.email

The result queryset can be ordered by:

  • User.first_name
  • User.last_name
  • User.email
  • User.created_at

Example request:

GET /api/users/?o=created_at&ot=desc

Example response:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "slug": "alice",
            "email": "alice@djaodjin.com",
            "full_name": "Alice Cooper",
            "created_at": "2014-01-01T00:00:00Z"
        }
    ]
}