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.

**Examples

GET /api/billing/cowork/bank/ HTTP/1.1

responds

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

Queries a page (PAGE_SIZE records) of Transaction associated to {organization} while the organization acts as a subscriber.

The queryset can be filtered to a range of dates ([start_at, ends_at]) and for at least one field to match a search term (q).

Query results can be ordered by natural fields (o) in either ascending or descending order (ot).

This API end point is typically used to display orders, payments and refunds of a subscriber (see subscribers pages)

**Examples

GET /api/billing/xia/history?start_at=2015-07-05T07:00:00.000Z&o=date&ot=desc HTTP/1.1
{
    "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.

**Examples

GET /api/billing/cowork/card/ HTTP/1.1

responds

{
  "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.

**Examples

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

Queries a page (PAGE_SIZE records) of Coupon associated to a provider.

The queryset can be filtered to a range of dates ([start_at, ends_at]) and for at least one field to match a search term (q).

Query results can be ordered by natural fields (o) in either ascending or descending order (ot).

**Examples

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

retrieves the list of Coupon for provider cowork where code matches ‘DIS’, ordered by code in ascending order.

{
    "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
        }
    ]
}
GET /api/billing/:organization/coupons/:coupon/
PUT /api/billing/:organization/coupons/:coupon/
DELETE /api/billing/:organization/coupons/:coupon/
class saas.api.coupons.CouponDetailAPIView(**kwargs)

Retrieves a Coupon.

**Examples

GET /api/billing/cowork/coupons/DIS100 HTTP/1.1
 {
     "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)

Queries a page (PAGE_SIZE records) of Transaction marked as receivables associated to {organization} while the organization acts as a provider.

The queryset can be filtered to a range of dates ([start_at, ends_at]) and for at least one field to match a search term (q).

Query results can be ordered by natural fields (o) in either ascending or descending order (ot).

This API endpoint is typically used to find all sales for {organization} whether it was paid or not.

**Examples

GET /api/billing/cowork/receivables?start_at=2015-07-05T07:00:00.000Z&o=date&ot=desc HTTP/1.1
{
    "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)

Queries a page (PAGE_SIZE records) of Transaction associated to {organization} while the organization acts as a provider.

The queryset can be filtered to a range of dates ([start_at, ends_at]) and for at least one field to match a search term (q).

Query results can be ordered by natural fields (o) in either ascending or descending order (ot).

This API endpoint is typically used to find sales, payments, refunds and bank deposits for a provider. (see provider pages)

**Examples

GET /api/billing/cowork/transfers?start_at=2015-07-05T07:00:00.000Z&o=date&ot=desc HTTP/1.1
{
    "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)

Queries a page (PAGE_SIZE records) of Transaction from the ledger.

The queryset can be filtered to a range of dates ([start_at, ends_at]) and for at least one field to match a search term (q).

Query results can be ordered by natural fields (o) in either ascending or descending order (ot).

**Examples

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

responds

{
    "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)

Queries a page (PAGE_SIZE records) of Charge that were created on the processor.

The queryset can be filtered to a range of dates ([start_at, ends_at]) and for at least one field to match a search term (q).

Query results can be ordered by natural fields (o) in either ascending or descending order (ot).

**Examples

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

Retrieve the list of charges that were created before 2015-07-05T07:00:00.000Z, sort them by date in descending order.

{
    "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.

**Examples

GET /api/billing/charges/ch_XAb124EF/ HTTP/1.1
{
    "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

POST /api/billing/charges/ch_XAb124EF/email/  HTTP/1.1

responds

{
    "charge_id": "ch_XAb124EF",
    "email": "joe@localhost.localdomain"
}

The service sends a duplicate e-mail receipt for charge ch_XAb124EF to the e-mail address of the customer, i.e. joe@localhost.localdomain.

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

POST /api/billing/charges/ch_XAb124EF/refund/ HTTP/1.1
{
    "lines": [
      {
          "num": 0,
          "refunded_amount": 4000,
      },
      {
          "num": 1,
          "refunded_amount": 82120,
      }
  ]
}

Refunds $40 and $821.20 from first and second line item on the receipt respectively. The API call responds with the Charge.

{
    "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)

Adds a Plan into the 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.

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

**Examples

POST /api/cart/ HTTP/1.1
{
    "plan": "open-space",
    "option": 1
}

responds

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

option is optional. When it is not specified, subsquent checkout screens will provide choices to pay multiple periods in advance When additional full_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/
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.

**Examples

Content of names.csv:

POST /api/cart/:plan/upload/ HTTP/1.1

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

responds

{
    "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 a list indexed by plans of items that will be charged (lines) and options that could be charged instead.

In many subscription businesses, it is possible to buy multiple period in advance at a discount. The options reflects that.

**Examples

GET /api/billing/xia/checkout HTTP/1.1

responds

{"items":
[{
  "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":[]
}]
}

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.

**Examples

POST /api/profile/cowork/plans HTTP/1.1
{
    "title": "Open Space",
    "description": "A desk in our coworking space",
    "is_active": false,
    "period_amount": 12000,
    "interval": 1
}

responds

{
    "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)

Retrieves 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.

**Examples

GET /api/profile/cowork/plans/open-space HTTP/1.1
{
    "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.

**Examples

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

Retrieves profile information on an Organization.

**Examples

GET /api/profile/xia/ HTTP/1.1

responds

{
    "created_at": "2018-01-01T00:00:00Z",
    "email": "xia@locahost.localdomain",
    "full_name": "Xia Lee",
    "printable_name": "Xia Lee",
    "slug": "xia",
    "subscriptions": [
        {
            "created_at": "2018-01-01T00:00:00Z",
            "ends_at": "2019-01-01T00:00:00Z",
            "plan": "open-space",
            "auto_renew": true
        }
    ]
}
GET /api/users/:user/accessibles/
POST /api/users/:user/accessibles/
class saas.api.roles.AccessibleByListAPIView(**kwargs)

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

see Flexible Security Framework.

**Examples

GET  /api/users/alice/accessibles/ HTTP/1.1

responds

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created_at": "2018-01-01T00:00:00Z",
            "slug": "cowork",
            "printable_name": "ABC Corp.",
            "role_description": "manager",
            "request_key": null,
            "grant_key": null
        }
    ]
}
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.

**Examples

DELETE /api/profile/cowork/roles/managers/xia/ HTTP/1.1
GET /api/profile/:organization/roles/describe/
POST /api/profile/:organization/roles/describe/
class saas.api.roles.RoleDescriptionListCreateView(**kwargs)

Lists roles by description“RoleDescription“.

see Flexible Security Framework.

**Examples

GET /api/profile/cowork/roles/describe/ HTTP/1.1

responds

{
    "count": 2,
    "next": null,
    "previous": null,
    "results": [
        {
            "created_at": "2018-01-01T00:00:00Z",
            "title": "Managers",
            "slug": "manager",
            "is_global": true,
            "roles": [
                {
                    "created_at": "2018-01-01T00:00:00Z",
                    "user": {
                        "slug": "donny",
                        "email": "donny@localhost.localdomain",
                        "full_name": "Donny Cooper",
                        "created_at": "2018-01-01T00:00:00Z"
                    },
                    "request_key": null,
                    "grant_key": null
                },
            ]
        },
        {
            "created_at": "2018-01-01T00:00:00Z",
            "name": "Contributors",
            "slug": "contributor",
            "is_global": false,
            "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)

Retrieves a RoleDescription.

see Flexible Security Framework.

**Examples

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

responds

{
    "created_at": "2018-01-01T00:00:00Z",
    "name": "Managers",
    "slug": "manager",
    "is_global": true,
    "roles": [
        {
            "created_at": "2018-01-01T00:00:00Z",
            "user": {
                "slug": "donny",
                "email": "donny@localhost.localdomain",
                "full_name": "Donny Cooper",
                "created_at": "2018-01-01T00: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)

Lists all roles for an organization

**Examples

GET /api/profile/cowork/roles/ HTTP/1.1

responds

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "created_at": "2018-01-01T00:00:00Z",
            "role_description": {
                "name": "Manager",
                "slug": "manager",
                "organization": {
                    "slug": "cowork",
                    "full_name": "ABC Corp.",
                    "printable_name": "ABC Corp.",
                    "created_at": "2018-01-01T00:00:00Z",
                    "email": "support@localhost.localdomain"
                }
            },
            "user": {
                "slug": "alice",
                "email": "alice@localhost.localdomain",
                "full_name": "Alice Doe",
                "created_at": "2018-01-01T00:00:00Z"
            },
            "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.

**Examples

DELETE /api/profile/cowork/roles/managers/xia/ HTTP/1.1
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

**Examples

GET /api/profile/:organization/subscribers/?o=created_at&ot=desc HTTP/1.1
{
    "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.

**Examples

GET /api/profile/:organization/subscriptions/?o=created_at&ot=desc HTTP/1.1
{
    "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
        }
    ]
}
DELETE /api/profile/:organization/subscriptions/<subscribed_plan>/
class saas.api.subscriptions.SubscriptionDetailAPIView(**kwargs)

Retrieves a Subscription.

**Examples

GET /api/profile/cowork/plans/open-space/subscriptions/xia/ HTTP/1.1
{
    ... XXX ...
}

Metrics API

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

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

The queryset can be filtered to a range of dates ([start_at, ends_at]) and for at least one field to match a search term (q).

Query results can be ordered by natural fields (o) in either ascending or descending order (ot).

**Examples

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

responds

{
    "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)

Lists all Subscription to a plan whose provider is {organization} and which are currently in progress.

Optionnaly when an ends_at query parameter is specified, returns a queryset of Subscription that were active at ends_at. When a start_at query parameter is specified, only considers Subscription that were created after start_at.

The queryset can be filtered for at least one field to match a search term (q).

Query results can be ordered by natural fields (o) in either ascending or descending order (ot).

**Examples

GET /api/metrics/cowork/active?o=created_at&ot=desc HTTP/1.1
{
    "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).

**Examples

GET /api/metrics/cowork/balances HTTP/1.1
{
    "title": "Balances",
    "scale": 0.01,
    "unit": "usd",
    "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)

Queries a balance sheet named {report} for the broker.

To add lines in the report see /api/metrics/balances/{report}/lines/.

**Examples

GET /api/metrics/balances/taxes/ HTTP/1.1

responds

{
    "scale": 0.01,
    "unit": "usd",
    "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)

Queries the list of rows reported on a balance sheet named {report}.

**Examples

GET  /api/metrics/balances/taxes/lines/ HTTP/1.1

responds

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "title": "Sales",
            "selector": "Receivable",
            "rank": 1
        }
    ]
}
GET /api/metrics/:organization/churned/
class saas.api.subscriptions.ChurnedSubscriptionAPIView(**kwargs)

Lists 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 result queryset can be ordered.

**Examples

GET /api/metrics/cowork/churned?o=created_at&ot=desc HTTP/1.1
{
    "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)

Queries a page (PAGE_SIZE records) of Coupon usage.

The queryset can be filtered to a range of dates ([start_at, ends_at]) and for at least one field to match a search term (q).

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

**Examples

GET /api/metrics/cowork/coupons/DIS100/ HTTP/1.1
{
    "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

**Examples

GET /api/metrics/cowork/customers HTTP/1.1
{
    "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)

Produces sales, payments and refunds over a period of time.

**Examples

GET /api/metrics/cowork/funds/ HTTP/1.1
{
    "title": "Amount",
    "scale": 0.01,
    "unit": "usd",
    "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

**Examples

GET /api/metrics/cowork/plans HTTP/1.1
{
    "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)

Queries all Organization.

**Examples

GET /api/profile/?o=created_at&ot=desc HTTP/1.1
{
    "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)

Queries a page (PAGE_SIZE records) of User.

The queryset can be filtered to a range of dates ([start_at, ends_at]) and for at least one field to match a search term (q).

Query results can be ordered by natural fields (o) in either ascending or descending order (ot).

**Examples

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

responds

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