Getting Started =============== Get an auth token ----------------- A core auth token will provide access to all data resources for a :term:`flock`. .. code-block:: http $ 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. .. code-block:: http HTTP/1.1 200 OK { "api_key": "7ba68f4c99" } For cURL users the syntax is more verbose: .. code-block:: http $ 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 .. code-block:: http $ 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 (:term:`flock`) but you can verify which flocks a user has permissions to access with the base ``/api/v1/`` call. .. code-block:: http 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. .. code-block:: http /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) .. code-block:: http 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``) .. code-block:: http 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``) .. code-block:: http 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``) .. code-block:: http 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 .. code-block:: http http https://api.sheepcrm.com/api/v1/$FLOCK/{resource}/ Authorization:"Bearer $API_KEY" include_deleted==Y Show only deleted records .. code-block:: http 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. .. code-block:: json { "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. .. code-block:: http 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`` .. code-block:: http 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 ---------------------- .. code-block:: http http DELETE https://api.sheepcrm.com/api/v1/example/person/5e44020149c3a85acee1ff9b/ Authorization:"Bearer $API_KEY" Restore a deleted record .. code-block:: http 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 .. code-block:: http 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 .. code-block:: http 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. .. code-block:: http 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 --------------------------------------------------- .. code-block:: http 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 -------------------------------------------- .. code-block:: http 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 .. code-block:: http 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" } .. code-block:: http 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) .. code-block:: http 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 .. code-block:: http http POST https://api.sheepcrm.com/api/v1/{flock}/{resource_type}/{uid}/touch/