Getting Started

Get an auth token

A core auth token will provide access to all data resources for a flock.

$ http POST https://api.sheepcrm.com/api/v1/auth/ username=james@james-webster.co.uk password=password

HTTP/1.1 403 FORBIDDEN
{
    "error": "Unable to authenticate",
    "error_detail": "Username and Password do not match an account"
}

that’s not the password… With correct credentials you should get an api key returned.

HTTP/1.1 200 OK
{
        "api_key": "7ba68f4c99"
}

For cURL users the syntax is more verbose:

$ curl https://api.sheepcrm.com/api/v1/auth/ -H 'Content-Type: application/json' -d '{"username":"james@james-webster.co.uk","password":"password"}'

HTTP/1.1 200 OK
{
        "api_key": "7ba68f4c99"
}

Making an authenticated request

Get a list of resource types for the client account (& records numbers) checks auth to the flock and provides a lookup for the different resource_types. resource_types are the Sheep name for what might normally be expected to be a database table or collection

$ http https://api.sheepcrm.com/api/v1/$FLOCK/ Authorization:"Bearer $API_KEY"

HTTP/1.1 200 OK
{
  "resource_type": [
    {
      "count": 6,
      "name": "activity"
      "last_modified": "2017-03-28T18:57:47.637000",
    },
    {
      "count": 5,
      "name": "allocation"
      "last_modified": "2017-03-28T18:57:47.637000",
    },
    ...
    ]
}

List available databases (flocks)

A typical user will only be connected to a single database (flock) but you can verify which flocks a user has permissions to access with the base /api/v1/ call.

http GET https://api.sheepcrm.com/api/v1/ Authorization:"Bearer $API_KEY"
HTTP/1.1 200 OK

{
    "flocks": [
        {
            "identifier": "example",
            "name": "Sheep Example"
        },
        {
            "identifier": "example-association",
            "name": "Example Association"
        },
        {
            "identifier": "example-family",
            "name": "Example Family"
        },
    ]
}

Create a resource

Resources are the data objects in Sheep. Each resource has it’s own schema but the API calls to interact with resources are all the same.

/api/v1/$FLOCK/{resource_type}/

http POST https://api.sheepcrm.com/api/v1/$FLOCK/person/ Authorization:"Bearer $API_KEY" first_name=Jim last_name=Lovell
HTTP/1.1 201 CREATED

{
    "bucket": "example",
    "data": {
        ...
        "first_name": "Jim",
        "last_name": "Lovell",
        ...
    },
    "display_value": "an empty person",
    "links": [
        ...
    ],
    "meta": {
        "created": "2020-02-12T13:47:45.695000",
        "last_updated": "2020-02-12T13:47:45.730000",
        "state": "updated"
    },
    "resource": "person",
    "uri": "/example/person/5e44020149c3a85acee1ff9b/"
}

(empty fields removed for brevity)

Get all resources of a given type

(Example limited to a page size of 1)

http https://api.sheepcrm.com/api/v1/$FLOCK/person/\?page_size\=1 Authorization:"Bearer $API_KEY"
HTTP/1.1 200 OK
{
    "grand_total": 1216,
    "links": [
        ...
    ],
    "page": 1,
    "page_size": 1,
    "pages": 1216,
    "results": [
        {
            "_id": null,
            "bucket": "example",
            "created": "2015-01-05T20:44:34.447000",
            "data": {
                "abilities": [
                    "usher"
                ],
                "address_lines": [
                    "Studio 6"
                ],
                "adult": true,
                "anniversary": null,
                "authorised_pickup": null,
                "automatic_email_opt_out": null,
                "bio": null,
                "colour": null,
                "comms_permission": [
                    null,
                    "sms",
                    "telephone"
                ],
                "connections": [
                    null,
                    "/example/organisation/54aaf9763078f80f3ed8ca0b/;Grant Recipient",
                    "/example/organisation/54aaf97b3078f80f3ed8cad7/;Accreditation Contact",
                    "/example/organisation/54aaf97b3078f80f3ed8cad7/;Garden Contact",
                    "/example/organisation/54aaf97d3078f80f3ed8cb42/;Charity Fundraiser",
                    "/example/organisation/54aaf9853078f80f3ed8cc9b/;Manager",
                    "/example/person/5746cfa53078f87b2bc3e177/;shared interest"
                ],
                "country": "UK",
                "date_of_birth": null,
                "date_of_death": null,
                "deceased": null,
                "domain": null,
                "driving_licence": null,
                "editable_formatted_name": null,
                "editable_salutation": null,
                "email": [
                    "danied@home.com;home",
                    "daniel.abbott@company.com;work__primary"
                ],
                "email_opt_out": false,
                "emergency_contact_details": null,
                "emergency_contact_details_2": null,
                "expertise": null,
                "external_ids": [
                    null
                ],
                "external_photo_url": null,
                "facebook_username": null,
                "first_name": "Daniel",
                "formatted_name": "Mr Daniel I Abbott",
                "gender": null,
                "geo": null,
                "gocardless_uid": null,
                "has_direct_debit_mandate": null,
                "hide_from_views": false,
                "initial": "I",
                "instagram_username": null,
                "interests": [
                    "Baking",
                    "Volunteering"
                ],
                "iso_country": "GB",
                "job_title": "Administrator",
                "known_as": null,
                "language": null,
                "last_name": "Abbott",
                "legacy_uid": null,
                "linkedin_public_profile": null,
                "locality": "Witney",
                "mailchimp_last_sync": null,
                "mailsort_code": null,
                "member_original_join_date": null,
                "member_since": null,
                "name_suffix": null,
                "notes": null,
                "photo": "https://s3-eu-west-1.amazonaws.com/sheepcrm/example/person/54aaf7b23078f80d90d8ca7b/photo/54.jpg",
                "photo_required": null,
                "postal_code": "OX28 6AL",
                "region": "Oxfordshire",
                "salutation": "Mr Abbott",
                "school": null,
                "school_year": null,
                "school_year_modifier": null,
                "sen": null,
                "skype_username": null,
                "sortable_name": "abbott daniel i mr",
                "source": null,
                "stripe_last_sync": null,
                "stripe_uid": null,
                "tags": [
                    "bad-tag",
                    "blue iguana",
                    "donor",
                    "family",
                    "gift-aid",
                    "mynewtag",
                    "trustee",
                    "🐑 member"
                ],
                "telephone": [
                    "01234 567 891;work",
                    "01993 700 100;home"
                ],
                "test": null,
                "time_zone": null,
                "title": "Mr",
                "twitter_username": "example",
                "vend_uid": null,
                "website": "example.com",
                "xero_last_sync": null,
                "xero_uid": null
            },
            "display_value": "Mr Daniel I Abbott",
            "id": "54aaf7b23078f80d90d8ca7b",
            "last_updated": "2020-02-24T00:09:05.852000",
            "links": [
                ...
            ],
            "permissions": {
                ...
            },
            "resource": "person",
            "state": "updated",
            "uri": "/example/person/54aaf7b23078f80d90d8ca7b/"
        }
    ],
    "total": 1216
}

Query logic

Append the field name with a modifier to use query logic. e.g. amount__gte=5 results where amount is 5 or more

__and

and list

__eq

exact

__gt

greater than

__gte

greater than or equals

__lt

less than

__lte

less than or equals

__ne

not equal to

__near

near

__none

none of

__or

or list

__raw

raw

__startswith

starts with

__startswithi

starts with case insensitive

Querying

Each resource type can be queried using the same RESTful methods

All people called James (/{flock}/person/?first_name=james)

http https://api.sheepcrm.com/api/v1/$FLOCK/person/ Authorization:"Bearer $API_KEY" first_name==james

All people called James Webster (/{flock}/person/?first_name=james&last_name=webster&mode=AND)

http https://api.sheepcrm.com/api/v1/$FLOCK/person/ Authorization:"Bearer $API_KEY" first_name==james last_name==webster mode==AND

All people called James or last name Webster (/{flock}/person/?first_name=james&last_name=webster&mode=OR)

http https://api.sheepcrm.com/api/v1/$FLOCK/person/ Authorization:"Bearer $API_KEY" first_name==james last_name==webster mode==OR

Special Queries

Include deleted records - use include_deleted=Y to included deleted records in your results

http https://api.sheepcrm.com/api/v1/$FLOCK/{resource}/ Authorization:"Bearer $API_KEY" include_deleted==Y

Show only deleted records

http https://api.sheepcrm.com/api/v1/$FLOCK/{resource}/ Authorization:"Bearer $API_KEY" include_deleted==Y state==deleted

Smart Dates

The following strings can be used in place of a date to represent a relative date

  • last month (today minus one month)

  • last week (today minus one month)

  • last year (this time last year)

  • next month (this time next month)

  • next week (this time next week)

  • next year (this time next year)

  • start_of_month (start of this month)

  • start_of_year (start of this year)

  • today (now, including current time)

  • tomorrow (this time tomorrow)

  • year_ago (this time a year ago)

  • yesterday (this time yesterday)

Paging results

Queries against the Sheep API use a default page size of 25. The page size can be set using the page_size parameter and used in conjunction with the page parameter to iterate through all results. The pages value provided in data packet idicats how many pages to expect. Internally we use page sizes up to 1000 (beyond 1000 it is typically quicker to make multiple smaller calls), the maximum allowed is currently 1500.

{
    "grand_total": 1216,
    "links": [
        ...
    ],
    "page": 1,
    "page_size": 25,
    "pages": 1216,
    "results": [
    ...
    ]
}

To query all results you should read the number of page from the first response and loop until the page requested matches the number of pages available.

http https://api.sheepcrm.com/api/v1/$FLOCK/person/ Authorization:"Bearer $API_KEY" first_name==james

http https://api.sheepcrm.com/api/v1/$FLOCK/person/ Authorization:"Bearer $API_KEY" first_name==james page=2

http https://api.sheepcrm.com/api/v1/$FLOCK/person/ Authorization:"Bearer $API_KEY" first_name==james page=3

Note

Sheep uses page based pagination not cursor based pagination. Applications must be aware of the limitations e.g. data changing between page requests, possible duplicates and missing records across pages.

Get a single resource record

e.g. uri = /example/person/5e44020149c3a85acee1ff9b/

This is the record that we created earlier with just the first name “Jim” and last name “Lovell”. Most other data fields are empty null but some are generated by the system e.g. formatted_name

http https://api.sheepcrm.com/api/v1/example/person/5e44020149c3a85acee1ff9b/ Authorization:"Bearer $API_KEY"
HTTP/1.1 200 OK

{
    "bucket": "example",
    "data": {
        "abilities": [
            null
        ],
        "address_lines": [
            null
        ],
        "adult": null,
        "anniversary": null,
        "authorised_pickup": null,
        "automatic_email_opt_out": null,
        "bio": null,
        "colour": null,
        "comms_permission": [
            null
        ],
        "connections": [
            null
        ],
        "country": null,
        "date_of_birth": null,
        "date_of_death": null,
        "deceased": null,
        "domain": null,
        "driving_licence": null,
        "editable_formatted_name": null,
        "editable_salutation": null,
        "email": [
            null
        ],
        "email_opt_out": null,
        "emergency_contact_details": null,
        "emergency_contact_details_2": null,
        "expertise": null,
        "external_ids": [
            null
        ],
        "external_photo_url": null,
        "facebook_username": null,
        "first_name": "Jim",
        "formatted_name": "Jim Lovell",
        "gender": null,
        "geo": null,
        "gocardless_uid": null,
        "has_direct_debit_mandate": null,
        "hide_from_views": false,
        "initial": null,
        "instagram_username": null,
        "interests": [
            null
        ],
        "iso_country": null,
        "job_title": null,
        "known_as": null,
        "language": null,
        "last_name": "Lovell",
        "legacy_uid": null,
        "linkedin_public_profile": null,
        "locality": null,
        "mailchimp_last_sync": null,
        "mailsort_code": null,
        "member_original_join_date": null,
        "member_since": null,
        "name_suffix": null,
        "notes": null,
        "photo": null,
        "photo_required": null,
        "postal_code": null,
        "region": null,
        "salutation": "Sir",
        "school": null,
        "school_year": null,
        "school_year_modifier": null,
        "sen": null,
        "skype_username": null,
        "sortable_name": "lovell jim",
        "source": null,
        "stripe_last_sync": null,
        "stripe_uid": null,
        "tags": [
            null
        ],
        "telephone": [
            null
        ],
        "test": null,
        "time_zone": null,
        "title": null,
        "twitter_username": null,
        "vend_uid": null,
        "website": null,
        "xero_last_sync": null,
        "xero_uid": null
    },
    "display_value": "Jim Lovell",
    "links": [
        ...
    ],
    "meta": {
        "created": "2020-02-12T13:47:45.695000",
        "last_updated": "2020-02-12T13:47:45.813000",
        "state": "updated"
    },
    "resource": "person",
    "uri": "/example/person/5e44020149c3a85acee1ff9b/"
}

Delete a single record

http DELETE https://api.sheepcrm.com/api/v1/example/person/5e44020149c3a85acee1ff9b/ Authorization:"Bearer $API_KEY"

Restore a deleted record

http POST https://sheepcrm.com/api/v1/example/person/5e44020149c3a85acee1ff9b/restore/ "Authorization: Bearer $API_KEY"

Update a record

PUT a json packet, multiple fields allowed

http PUT https://api.sheepcrm.com/api/v1/example/person/5e44020149c3a85acee1ff9b/ Authorization:"Bearer $API_KEY" first_name=Jim

HTTP/1.1 200 OK

{
        "first_name": "Jim",
}

Updating with a file

The journal resource has a files field. In this example using the httpie command line we upload a photo called beer.jpg

http PUT https://api.sheepcrm.com/api/v1/example/journal/623c6d09eb69265e5de83da5/ Authorization:"Bearer $API_KEY" files@'beer.jpg;type=image/jpg'

HTTP/1.1 200 OK
{
    "errors": {},
    "updates": {
        "files": [
            "https://sheepcrm.s3.amazonaws.com/example/journal/623c6d09eb69265e5de83da5/files/beer.jpg",
        ]
    }
}

Obfuscate a single record

obfuscate a record to remove personal data but keep the record for auditing and reporting.

http PUT https://api.sheepcrm.com/api/v1/example/person/5e44020149c3a85acee1ff9b/obfuscate/ Authorization:"Bearer $API_KEY"

Get the display value for a single resource record

http https://api.sheepcrm.com/api/v2/example/person/5e44020149c3a85acee1ff9b/display Authorization:"Bearer $API_KEY"
HTTP/1.1 200 OK

{
"display_value": "Jim Lovell"
}

Get the avatar for a single resource record

http https://sls-api.sheepcrm.com/api/v2/example/person/5e44020149c3a85acee1ff9b/avatar
HTTP/1.1 200 OK

        +------------------------------+
        | NOTE: binary data not shown  |
        +------------------------------+

Getting a signed URL

Some resources do not require authentication but are signed for additional security e.g. a membership card

http https://api.sheepcrm.com/api/v2/example/member/5e44020149c3a85acee1ff9b/card/
HTTP/1.0 401 Unauthorized

{
    "description": "a signature parameter is required when requesting a signed url",
    "link": {
        "href": "https://docs.sheepcrm.com/",
        "rel": "help",
        "text": "Documentation related to this error"
    },
    "title": "signature missing"
}
http https://api.sheepcrm.com/api/v2/example/member/5e44020149c3a85acee1ff9b/card/ signature==38c36ebd5fa6020605cef7c18cd4f75f835916cf2d0b70b7b9818cc72387d828
HTTP/1.0 200 OK

Recalculating a record

force

some resources accept a force param to recalcate related resources (force will typically be slower)

http POST https://api.sheepcrm.com/api/v1/{flock}/{resource_type}/{uid}/recalc/
HTTP/1.0 200 OK

{
    "status": "OK",
    "force": false
}

Touch

Update the update the timestamp on a record

http POST https://api.sheepcrm.com/api/v1/{flock}/{resource_type}/{uid}/touch/