Link2Feed RESTful Client and Appointment API

Link2Feed RESTful Client and Appointment API

This space documents the general process for authenticating against and utilizing the Client and Appointment API. This is the core API behind our CNCT tool and allows the following interactions:

  • Creating New Clients and their Households

  • Updating Existing Clients and their Households

  • Booking Appointments for the Future

  • Updating Existing Appointments

  • Cancelling Existing Appointments

Any questions, queries or concerns can be forwarded to our support team by emailing support@link2feed.com and requesting assistance. To sign up to use this API, please contact your account manager.

 

Authentication

All API requests are authenticated using HMAC Signed Requests and an API Key. This is similar to the method that AWS uses for many of its API requests.

Required Credentials

To sign a request, you need the following three pieces of information, provided by Link2Feed:

  • API Key - To be sent as part of HTTP request and direct authorization

  • Secret Key - To be used to sign the HTTP request, but not sent along with the request

  • URL - The endpoint that will receive and process the request

Required HTTP Headers

  • Host

    • Hostname of the targeted endpoint

    • Will change per-environment. eg- example.com

  • Authorization

    • Calculated signature based on the contents of the request

    • Will change per-request. eg- HMAC-SHA256 0fa36b84ab47a14ec56934927105e56d83424ec5bd649680e0d52bbb89e28ed0

  • Signed-Headers

    • Headers signed against, in addition to the request body, that are included in the signature. Note that this is case-sensitive.

    • Exactly: host,signed-headers

  • X-API-Key

    • API Key provided by Link2Feed Staff. eg- 6934927105e56d83424ec5bd64

Signing Process

  1. Gather Required Information:

    1. HTTP Method eg- GET/POST/PUT/PATCH/DELETE

    2. HTTP URL, including query parameters eg- https://example.com/api/v1/demo?id=1234

    3. Request Payload/Body

    4. Request Headers

  2. Combine and Format Data to Be Signed

    1. The data must be “escaped” for safe transit.

    2. The data is to be concatenated. Ordering of the fields need only be internally-consistent, so the data sent must match the order of the fields in the data that is signed.

    3. The package to be signed consists of three parts:

      1. A Request Line: A string consisting of the HTTP Request Line format, notably “The Request-Line begins with a method token, followed by the Request-URI and the protocol version, and ending with CRLF. The elements are separated by SP characters. No CR or LF is allowed except in the final CRLF sequence.” For example: POST /api/v1/clients/find HTTP/1.1\r\n

      2. The Signed Headers: Specifically, these are the Host and Signed-Headers headers, and their contents. Formatted as header-name, followed by a colon and a space, then the value of the header. Each header is followed by a CRLF. For example: host: redacted.link2feed.com\r\nsigned-headers: host,signed-headers\r\n

      3. The Body of the Request: If the request is JSON-formatted (ie- Content-Type is application/json) then this is simply the JSON String. If the request is formatted as form-data, each key/value pair must be a) “escaped” for safe HTTP transfer, b) split into Key and Value, c) represented as Key=Value, and d) the collection must be joined together with ampersands between key/value pairs. For example, if the form-data is firstName: Eleven, lastName: O'Clock, dob: 1980-01-01, then the body to be signed would be: firstName=Eleven&lastName=O%27Clock&dob=1980-01-01 where, notably, the ' in O'clock is escaped to %27.

    4. Combine the three parts into a single string, separated by CRLF characters. For example the above:

      POST /api/v1/clients/find HTTP/1.1\r\nhost: redacted.link2feed.com\r\nsigned-headers: host,signed-headers\r\n\r\nfirstName=Eleven&lastName=O%27Clock&dob=1980-01-01

      Note: As each header ends with a CRLF and then the joining adds another, there are two CRLF character blocks between the headers and the body. The same request as JSON, and with the CRLF characters rendered would be:

      POST /api/v1/clients/find HTTP/1.1 host: redacted.link2feed.com signed-headers: host,signed-headers { "firstName":"Eleven", "lastName":"O'Clock", "dob":"1980-01-01" }
  3. Build the Signature

    1. Once the string is ready to be signed, it must go through two main processes:

      1. Gathering the HMAC SHA-256 hash of the contents, signed with the Secret Key provided by Link2Feed

      2. Converting the resultant hash to Base64

  4. Send the Request

    1. Once the Base64’ed value of the HMAC SHA-256 hash is collected, it is added as an additional “Authorization” header to the request in the form HMAC-SHA256 _______CalculatedHash_______.

    2. The request can then be sent. It must include both the HMAC signature as an Authorization header, and the API-Key as an X-API-Key header. So for example, the above JSON example request (signed against a secret key of 123456789) would produce the following request headers:

      Authorization: "HMAC-SHA256 3deOvVHhL1zyHyS7+cWPsPW+OnhxQXHJzLsR9UyAIQ4="

      Signed-Headers: "host,signed-headers"

      X-API-Key: "6934927105e56d83424ec5bd64"

      Content-Type: "application/json"

      Host: "redacted.link2feed.com"

       

JavaScript Example

The following is built against Postman (https://www.postman.com/) Pre-request Scripts (https://learning.postman.com/docs/writing-scripts/pre-request-scripts/). Working sample Collections for Postman are included at the bottom of this document as Appendix A.

Notable changes to adapt this elsewhere: pm.variables.get() is used to pull Postman’s environment variables out, and are used here to pull the Secret and URL. If adapting this to other uses, replace the SECRET_KEY variable, and adapt the SIGNED_HEADERS constant to refer to the hostname from a given source.

The signed header that would go into an Authorization header can be produced from a call to, for example, getAuthHeader("GET", "https://example.com/api/v1/demo", '{"sample":"data"}', {"X-API-Key": "6934927105e56d83424ec5bd64", "Host": "example.com", "Signed-Headers": "host,signed-headers"})

Notably below, some shortcuts are taken using the Postman objects. Specifically:

  • request['data'] is a Postman RequestBody object, which is effectively in the context of this sample an Object or Key/Value store (ie- A form/json data element named foo is accessed as request['data']['foo']).

  • request['headers'] is a Postman HeaderList object, which is effectively in the context of this sample an Object or Key/Value store (ie- The host header is accessed as request['headers']['host']).

var SECRET_KEY = pm.variables.get("SECRET"); var SIGNED_HEADERS = [ ["host", pm.variables.get("API_URL")] ]; var SIGNED_HEADER = "signed-headers: host,signed-headers\r\n"; function getPath(url) { var pathRegex = /.+?\:\/\/.+?(\/.+?)(?:#|\?|$)/; var result = url.match(pathRegex); return result && result.length > 1 ? result[1] : ''; } function getQueryString(url) { var arrSplit = url.split('?'); if(arrSplit.length == 1) return ''; var params = arrSplit[1].split('&'); params.sort(); return '?'+params.join('&'); } function getAuthHeader(httpMethod, requestUrl, requestBody, requestHeaders) { if (httpMethod == 'GET' || !requestBody) { requestBody = ""; } else { if(requestHeaders != null && requestHeaders["content-type"] != "application/json") { var output = ""; Object.keys(requestBody).forEach(function(e) { output += escape(e) + "=" + escape(requestBody[e]) + "&"; }); requestBody = output.substring(0, output.length -1); // Remove the last & } } var requestLine = httpMethod +" "+getPath(requestUrl)+getQueryString(requestUrl)+" HTTP/1.1"; var headers = ""; for(var i = 0; i < SIGNED_HEADERS.length; ++i) { headers += (SIGNED_HEADERS[i][0] + ': ' + SIGNED_HEADERS[i][1] + '\r\n'); } headers += SIGNED_HEADER; var body = requestBody; var hashedRequestData = [requestLine, headers, body].join('\r\n'); var hmacDigest = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(hashedRequestData, SECRET_KEY)); var authHeader = "HMAC-SHA256 "+hmacDigest; return authHeader; } pm.environment.set("HMAC_AUTH_HEADER", getAuthHeader(request['method'], request['url'], request['data'], request['headers']));

Additional Documentation

  1. AWS Signing and authenticating REST requests: https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html

  2. ApiAuth - HMAC authentication for Rails and HTTP Clients: https://github.com/mgomes/api_auth

  3. HMAC on Wikipedia: https://en.wikipedia.org/wiki/HMAC

  4. Online HMAC Generator: https://codebeautify.org/hmac-generator

  5. IETF RFC 2104 - HMAC: Keyed-Hashing for Message Authentication: https://tools.ietf.org/html/rfc2104

  6. HMAC Tools for Various Languages

    1. C: https://github.com/ogay/hmac

    2. Java: https://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#HmacEx

    3. JavaScript/NodeJS: https://nodejs.org/api/crypto.html#crypto_class_hmac

    4. PHP: https://www.php.net/manual/en/function.hash-hmac.php

    5. Python: https://docs.python.org/3/library/hmac.html

    6. Ruby: https://ruby-doc.org/stdlib-2.4.0/libdoc/openssl/rdoc/OpenSSL/HMAC.html

Data Types API

Purpose: This endpoint is used to gather network-specific identifiers and other configuration data. Some of it is very CNCT-specific (eg- customized text blocks for the CNCT UI) but the big value is in the data types that must be passed along as part of the required details configured in the API.

HTTP URL: https://{{ HostName }}/api/v1/datatypes where {{ HostName }} is provided by Link2Feed, and varies depending on the environment (Test, Live, Staging, etc) being accessed.

HTTP Method: GET

Request Headers: Authorization, Host, Signed-Headers, X-API-Key

Request Payload: Nothing

Response Format: JSON Object

Response Fields:

  • Data Types – Many of the fields in Link2Feed are stored with a human-readable label (eg- “Own House”) and a more machine-friendly name (eg- “own_house”). When interacting with people, it is best to use the label. When building requests to create or update client details, the system expects the machine-friendly name instead of the label.

    • maritalStatuses: Network-specific options for the Marital Status question in the client profile, in the form of name/label.

    • genders: Network-specific options for the Gender question in the client profile, in the form of name/label.

    • housingTypes: Network-specific options for the Housing Types question in the client profile, in the form of name/label.

    • ethnicities: Network-specific options for the Ethnicities question in the client profile, in the form of name/label.

    • selfIdentificationTypes: Network-specific options for the Self Identifies As question in the client profile, in the form of name/label.

    • educationTypes: Network-specific options for the Highest Education Level Completed question in the client profile, in the form of name/label.

    • employmentTypes: Network-specific options for the Employment Type question in the client profile, in the form of name/label.

    • income_sourceTypes: Network-specific options for the Income Type question in the client profile, in the form of name/label.

    • relationships: Network-specific options for the Relationship question in the profile of secondary household members, in the form of name/label.

    • socialProgramTypes: Network-specific options for the Social Programs that the client is receiving in the client profile, in the form of name/label.

    • expenseTypes: Network-specific options for the Expense Type question in the client profile, in the form of name/label.

    • referredBy: Network-specific options for the Referred By question in the client profile, in the form of name/label.

    • dietaryConsiderationTypes: Network-specific options for the Dietary Considerations question in the client profile, in the form of name/label.

    • languageTypes: Network-specific options for the Languages question in the client profile, in the form of name/label.

  • Other Configuration Fields

    • states: Network-specific list of States or Provinces where agencies currently have sites within Link2Feed.

    • agencies: A list of Link2Feed agencies that currently have appointment programs available for booking through the API. Each record includes the agency name, its Link2Feed unique ID number, and a listing of its address to share with the client when considering which location to book at.

    • questionPhrasing: A Network-specific list of text bites that have been selected in the CNCT dashboard to provide specific user-friendly prompts for each question.

    • welcomeMessage: Network-specific text block used to represent the very first text on the CNCT landing page.

    • informationDisclaimer: Network-specific text block that is either the network’s current information-sharing consent disclaimer in Link2Feed, or a custom textbox setup in the CNCT dashboard.

    • consentDisclaimer: Network-specific text block that provides a user-friendly prompt for asking the user if they consent to being contacted.

    • householdMessage: Network-specific text block that provides a user-friendly prompt at the top of the Household Members page of CNCT.

    • thankYouMessage: Network-specific text block that provides a user-friendly message at the end of the client intake process of CNCT.

    • imageUrl: A URL that can be set in the CNCT dashboard for an image to display to users in CNCT.

    • foodBankName: The name of the Network that all of these details are drawn from.

    • enabledFields: A network-specific list that can be edited in the CNCT dashboard to select which of the common fields are turned on or off.

    • dateFormat: The date format to display and transfer dates.

    • useAutocomplete: A CNCT configuration flag for whether or not the network uses address autocomplete at all.

    • useUSPSAutocomplete: A CNCT configuration flag for whether or not to use specifically the USPS autocomplete system.

Response Codes:

  • 200 - OK. Response payload includes the data types details.

  • 401 - Unauthorized. There was an issue with the request. Ensure that all required headers are accurate (X-API-Key, Authorization, Signed-Headers and Host).

  • 5XX - Server Error. Any 5XX error (500, 502, 503, 504) means a Link2Feed error has occurred. Please contact Link2Feed if this persists.

Sample Response:

{ "maritalStatuses": [ { "label": "Single", "name": "single" }, { "label": "Married", "name": "married" }, ,,, ], "genders": [ { "label": "Female", "name": "female" }, ... ], "housingTypes": [ { "label": "Own House", "name": "own_house" }, { "label": "Rental", "name": "rental" }, ... ], "ethnicities": [ { "label": "White / Anglo", "name": "white_anglo" }, { "label": "Black / African American", "name": "black" }, { "label": "Hispanic / Latino", "name": "hispanic_latino" }, ... ], "selfIdentificationTypes": [ { "label": "Veteran", "name": "veteran" }, { "label": "Other", "name": "other" }, { "label": "None", "name": "none" }, ... ], "educationTypes": [ { "label": "Grades 0-8", "name": "grade_0_8" }, { "label": "Grades 9-11", "name": "grade_9_11" }, { "label": "High School Diploma", "name": "grade_12" }, ... ], "employmentTypes": [ { "label": "Post Secondary Student", "name": "student" }, { "label": "Full-Time", "name": "full_time" }, { "label": "Part-Time", "name": "part_time" }, ... ], "income_sourceTypes": [ { "label": "TEFAP Ineligible", "name": "tefap_ineligible" }, { "label": "None", "name": "none" }, { "label": "Pension", "name": "pension" }, ... ], "agencies": [ { "name": "Agency 01 - CSFP", "agencyId": 8105, "address": { "addressLine1": "1400 Independence Avenue SW", "addressLine2": "", "city": "Washington", "state": "Michigan", "ward": "District of Columbia", "postcode": "20250" } }, { "name": "Agency 04 - Appointment", "agencyId": 7315, "address": { "addressLine1": "164 Hoard Way", "addressLine2": "", "city": "Lexington", "state": "Kentucky", "ward": "Fayette", "postcode": "40596" } }, ... ], "relationships": [ { "label": "Spouse", "name": "spouse" }, { "label": "Child", "name": "child" }, { "label": "Parent", "name": "parent" }, ... ], "states": { "0": "Michigan", "1": "California", "2": "Texas", ... }, "socialProgramTypes": [ { "label": "WIC", "name": "wic" }, { "label": "Medical Healthcare (Medicare)", "name": "medical_healthcare_medicare" }, ... ], "expenseTypes": [ { "label": "Power", "name": "power" }, ... ], "referredBy": [ { "label": "Child Care Support", "name": "Child Care Support" }, { "label": "Community Support", "name": "Community Support" }, ... ], "dietaryConsiderationTypes": [ { "label": "Dairy", "name": "dairy" }, { "label": "Peanut Allergy", "name": "peanut_allergy" }, ... ], "languageTypes": [ { "label": "Abkhazian", "name": "Abkhazian" }, { "label": "Acoma", "name": "Acoma" }, ... ], "questionPhrasing": { "firstName": "<p>First Name&nbsp;</p>", "lastName": "Last Name&nbsp;", "dob": "Date of Birth (aka DOB) (1)", "noFixedAddress": "No Fixed Address / <b>Undisclosed</b>", "address": "Address Line 1", "address2": "Address Line 2", "city": "City1", "state": "State", "zipCode": "Zipcode", "county": "County", "gender": "Gender", "ethnicities": "What is your ethnicity?", "housingType": "Housing Type", "education": "Highest Education Level Completed", "employment": "Employment Type", "selfIdentifiesAs": "Self-Identifies As", "incomeType": "Primary Income Type", "otherIncomes": "Other Income Sources", "maritalStatus": "Marital Status", "householdMembers": "Household Members", "referredBy": "Referred By", "emailAndPhone": "Email and Phone", "relationships": "Relationship", "socialPrograms": "Receiving the Following Social Programs", "expenses": null, "dietaryConsiderationTypes": "Dietary Considerations", "languageTypes": null, "password1": "<p>Please Enter your <b>Password</b></p>", "password2": "Please Confirm your <b>Password</b>" }, "welcomeMessage": "<p>WELCOME</p>", "informationDisclaimer": "Testing", "consentDisclaimer": "CONTACT CONSENT", "householdMessage": "<strike style=\"\">CLIENT</strike> HOUSHOLD DETAILS", "thankYouMessage": "THANKS!", "imageUrl": "https://www.link2feed.com/wp-content/uploads/2016/08/L2F-Logo.png", "foodBankName": "Live Testing Network", "enabledFields": [ "clientProfileId", "addressLine1", "city", "state", "zipCode", "addressLine2", "county", "gender", "employmentType", "housingType", "educationType", "ethnicity", "selfIdentificationType", "maritalStatus", "incomeType", "income", "relationship", "otherIncomes", "socialProgramTypes", "referredBy", "dietaryConsiderationTypes" ], "dateFormat": "MM-dd-yyyy", "useAutocomplete": true, "useUSPSAutocomplete": false }

Clients API

Purpose: This collection of endpoints are used to create and update client profiles.

Find a Client by Minimal Details (First Name, Last Name and Date of Birth)

Purpose: This endpoint finds existing clients, or, failing to find an existing client, will return a new session key to begin interacting with the API to build a new client.

HTTP URL: https://{{ HostName }}/api/v1/clients/find where {{ HostName }} is provided by Link2Feed, and varies depending on the environment (Test, Live, Staging, etc) being accessed. Note: the URL Query Parameter skipDupecheck=truecan be appended to this URL (eg- .../clients/find?skipDupecheck=true) in order to skip duplicate checking. This may be desired to avoid potential privacy issues, depending on the access level of the tools utilizing this API.

HTTP Method: POST

Request Headers: Authorization, Content-Type, Host, Signed-Headers, X-API-Key

Request Payload: JSON Object
This object has three fields. If any of them are missing, the request will fail. These represent the client’s first name, last name, and date of birth. With these three identifiers most clients in the system can be uniquely identified.

{ "firstName":"Sample", "lastName":"Client", "dob":"1993-03-03" }

Response Format: JSON Object

Response Fields:

  • Always-Present Fields

    • clientProfileId: A globally-unique ID (GUID) representing the client sought for. This client may or may not already exist in the Link2Feed system. If the client already exists, the GUID represents their GUID in the database. If the client does not exist, a new GUID will be used to start a client-creation session. This can be triggered to always request a new GUID (ie- to skip the duplicate-checking process) by adding the query parameter skipDupecheck=true to the initial call.

    • filters: This array describes additional filters which may be applied to narrow down potential duplicates. Currently, the only filter available is an address filter, which provides several fake addresses and the real addresses of potential duplicates, masked to hide the address. For example if the client’s address were 1234 Cherry Lane, it would be masked to 1234 C****y L**e. This information can be sent to another endpoint to pick from existing duplicates.

  • Sometimes-Present Fields

    • link2feedId: If the client can be uniquely identified given the request details, the response will include their unique numerical identifier within the Link2Feed system.

Response Codes:

  • 200 - OK. Response payload includes the details requested.

  • 400 - Bad Request. Will respond with a message including details of the request field errors. For example: { "message": "firstName field not supplied." }

  • 401 - Unauthorized. There was an issue with the request. Ensure that all required headers are accurate (X-API-Key, Authorization, Signed-Headers and Host).

  • 5XX - Server Error. Any 5XX error (500, 502, 503, 504) means a Link2Feed error has occurred. Please contact Link2Feed if this persists.

Sample Response for No Client Found:

{ "clientProfileId": "9c5d7ccc-5874-4bfe-8a5b-97b70b1e932b", "filters": [] }

Sample Response for Found Single Client:

{ "clientProfileId": "37628109-abc1-41ab-891c-27175825d5cd", "link2feedId": 10275991, "filters": [] }

Sample Response for Found Multiple Clients:

{ "clientProfileId": "e7676973-7c29-4c86-bf1d-0a3377bb9c25", "filters": [ { "type": "text", "key": "address", "text": "What is your address?", "values": [ "9349 S********d C***t", "300 M**n S*", "503 S*******e P***a", "263 C*******n C****r", "146 S****y T*****e", "200 M**n A*e S*", "474 B***y T*****e" ] } ] }

 

Find a Client by Filters

Purpose: This endpoint potentially chooses a client from the potential filters. For example, the previous API endpoint could produce 7 address options. If this endpoint receives the correct session ID and address option to match an existing client, it will respond with a valid client option. If one of the invalid options is selected, however, it will respond with a new client session.

HTTP URL: https://{{ HostName }}/api/v1/clients/findbyfilters where {{ HostName }} is provided by Link2Feed, and varies depending on the environment (Test, Live, Staging, etc) being accessed.

HTTP Method: POST

Request Headers: Authorization, Content-Type, Host, Signed-Headers, X-API-Key

Request Payload: JSON Object
This object has two top-level fields. If any of them are missing, the request will fail. These represent the client’s GUID or profile ID, which is also the session key for working with this client, and also the specific filters chosen from previous filters.

{ "clientProfileId": "03885d38-1e22-40a1-a81c-9caf564057f4", "filters": [ { "key": "address", "value": "300 M**n S*" } ] }

Response Format: JSON Object

Response Fields:

  • Always-Present Fields

    • clientProfileId: A globally-unique ID (GUID) representing the client sought for. This client may or may not already exist in the Link2Feed system. If the client already exists, the GUID represents their GUID in the database. If the client does not exist, a new GUID will be used to start a client-creation session. Note: if an existing client is found, the clientProfileId provided by the response will differ from the clientProfileId provided in the request. If they are the same, it means a new client is being created.

  • Sometimes-Present Fields

    • filters: This array describes additional filters which may be applied to narrow down potential duplicates. Currently, the only filter available is an address filter so this will not be seen in practice as this response is only reached by providing an address, however, the system is extensible enough to provide other filtration plans to further sub-divide potential duplicates (in the case that first name, last name, date-of-birth and street address are not enough to uniquely identify a person.)

Response Codes:

  • 200 - OK. Response payload includes the details requested.

  • 400 - Bad Request. Will respond with a message including details of the request field errors. For example: { "message": "clientProfileId field not supplied." }

  • 401 - Unauthorized. There was an issue with the request. Ensure that all required headers are accurate (X-API-Key, Authorization, Signed-Headers and Host).

  • 5XX - Server Error. Any 5XX error (500, 502, 503, 504) means a Link2Feed error has occurred. Please contact Link2Feed if this persists.

Sample Response:

{ "clientProfileId": "e06e0bd4-ceb6-4017-860f-8a8fb03a92c7" }

 

Find a Client by ID (Client Profile ID or Link2Feed ID)

Purpose: This endpoint finds existing clients or fails loudly if it cannot find the client. This is in sharp comparison to the other client-finding endpoints which fail silently and encourage moving down the process of creating a new profile. This endpoint can be used to ensure that a client still exists in the Link2Feed system. This may not always be the case as clients are merged to resolve duplicate profile issues. This endpoint can also be used to convert Client Profile IDs to Link2Feed IDs and back.

HTTP URL: https://{{ HostName }}/api/v1/clients/{{ ID }} where {{ HostName }} is provided by Link2Feed, and varies depending on the environment (Test, Live, Staging, etc) being accessed. {{ ID }} is either the link2feedId or clientProfileId provided by any of the previous calls.

HTTP Method: GET

Request Headers: Authorization, Host, Signed-Headers, X-API-Key

Request Payload: None

Response Format: JSON Object

Response Fields:

  • Sometimes-Present Fields

    • clientProfileId: A globally-unique ID (GUID) representing the client sought for.

    • link2feedId: The client’s unique numerical identifier within the Link2Feed system.

Response Codes:

  • 200 - OK. Response payload includes the details requested.

  • 404 - Not Found. If the ID does not find a unique client, the 404 status will be returned. The payload will include an empty JSON object, with no fields.

  • 401 - Unauthorized. There was an issue with the request. Ensure that all required headers are accurate (X-API-Key, Authorization, Signed-Headers and Host).

  • 5XX - Server Error. Any 5XX error (500, 502, 503, 504) means a Link2Feed error has occurred. Please contact Link2Feed if this persists.

Sample Response for Found Single Client:

{ "clientProfileId": "37628109-abc1-41ab-891c-27175825d5cd", "link2feedId": 10275991 }

 

Find a Client’s Existing Details by ID (Client Profile ID or Link2Feed ID)

Purpose: This endpoint finds existing clients or fails loudly if it cannot find the client. This is in sharp comparison to the other client-finding endpoints which fail silently and encourage moving down the process of creating a new profile. This endpoint also provides a robust set of client personal information, and information for their household.

HTTP URL: https://{{ HostName }}/api/v1/clients/{{ ID }}/details where {{ HostName }} is provided by Link2Feed, and varies depending on the environment (Test, Live, Staging, etc) being accessed. {{ ID }} is either the link2feedId or clientProfileId provided by any of the previous calls.

HTTP Method: GET

Request Headers: Authorization, Host, Signed-Headers, X-API-Key

Request Payload: None

Response Format: JSON Object

Response Fields:

Several of the following fields refer to the data types retrieved from the data types API endpoint.

  • Sometimes-Present Fields

    • clientProfileId: A globally-unique ID (GUID) representing the client sought for.

    • link2feedId: The client’s unique numerical identifier within the Link2Feed system.

    • firstName: The client’s first name.

    • lastName: The client’s last name.

    • dateOfBirth: The client’s date of birth.

    • dobEstimated: A boolean flag for whether or not the above date of birth is an estimate.

    • agencyId: The ID of the client’s preferred agency.

    • noFixedAddress: A flag to check if the client has one of the undisclosed/no-fixed-address/prefer-not-to-answer addresses.

    • addressLine1: The first line of the client’s address.

    • addressLine2: The second line of the client’s address.

    • city: The city of the client’s address.

    • state: The state or province of the client’s address.

    • county: The county of the client’s address.

    • zipCode: The zip or postal code of the client’s address.

    • gender: The client’s gender as recorded in the system.

    • employmentType: The client’s recorded employment type.

    • educationType: The client’s highest received level of education.

    • ethnicity: An array representing the chosen ethnicities for the client.

    • housingType: The type of dwelling for the client.

    • selfIdentificationType: An array representing the chosen self-identifies as options for the client.

    • maritalStatus: The client’s recorded marital status.

    • income: The monthly value of the client’s primary income source.

    • incomeType: The type of income that the client receives as their primary income source.

    • otherIncomes: An array holding names of other income types that the client is receiving beyond their primary income source.

    • email: The client’s e-mail, if it exists. May be false if missing.

    • phoneNumber: The client’s phone number, if it exists. May be false if missing.

    • referredBy: The source of referral which directed the client to register at the food bank.

    • socialProgramTypes: An array holding names of any social programs that the client is eligible for.

    • expenseTypes: An array holding names of any expenses that the client is paying for.

    • dietaryConsiderationTypes: An array holding names of any dietary considerations in the household.

    • languageTypes: An array holding any languages spoken in the household.

    • householdMembers: An array holding client records (ie- all the fields above) for each additional client in the household. Plus the following fields unique to household members:

      • relationship: The relationship between this client, and the primary client being searched for by ID above.

Response Codes:

  • 200 - OK. Response payload includes the client details.

  • 404 - Not Found. If the ID does not find a unique client, the 404 status will be returned. The payload will include an empty JSON object, with no fields.

  • 401 - Unauthorized. There was an issue with the request. Ensure that all required headers are accurate (X-API-Key, Authorization, Signed-Headers and Host).

  • 5XX - Server Error. Any 5XX error (500, 502, 503, 504) means a Link2Feed error has occurred. Please contact Link2Feed if this persists.

Sample Response for Found Single Client:

{ "clientProfileId": "e06e0bd4-ceb6-4017-860f-8a8fb03a92c7", "link2feedId": 1029665, "firstName": "Sample", "lastName": "Person", "dateOfBirth": "01-01-1980", "dobEstimated": false, "agencyId": 8105, "noFixedAddress": "", "addressLine1": "300 Main St", "addressLine2": null, "city": "Gaithersburg", "state": "Maryland", "county": "Montgomery", "zipCode": "20878", "gender": "male", "employmentType": "declined_to_answer", "educationType": "do_not_know", "ethnicity": [ "declined_to_answer" ], "housingType": "individual", "selfIdentificationType": [ "do_not_know" ], "maritalStatus": "did_not_ask", "income": "0.00", "incomeType": "odsp", "otherIncomes": [], "email": false, "phoneNumber": false, "referredBy": "Emergency Shelter", "socialProgramTypes": [ "festival_program" ], "expenseTypes": [], "dietaryConsiderationTypes": [ "did_not_ask" ], "languageTypes": [], "householdMembers": [ { "clientProfileId": "d5ace4df-630a-45e8-a031-0eb93358a7b9", "link2feedId": 1029666, "firstName": "Other", "lastName": "Person", "dateOfBirth": "04-01-1999", "dobEstimated": false, "agencyId": 8105, "noFixedAddress": "", "addressLine1": "300 Main St", "addressLine2": null, "city": "Gaithersburg", "state": "Maryland", "county": "Montgomery", "zipCode": "20878", "gender": "other", "employmentType": "student", "educationType": "grade_9_11", "ethnicity": [ "other" ], "housingType": "individual", "selfIdentificationType": [ "other" ], "maritalStatus": "single", "income": 0, "incomeType": 0, "otherIncomes": [], "email": false, "phoneNumber": false, "referredBy": "Emergency Shelter", "socialProgramTypes": [], "expenseTypes": [], "dietaryConsiderationTypes": [], "languageTypes": [], "relationship": "other" } ] }

 

Add or Update Clients In the System

Purpose: This endpoint will allow either adding new clients (POST) or updating existing clients (PATCH). The fields required are listed in the data types API as enabledFields.

HTTP URL: https://{{ HostName }}/api/v1/clients where {{ HostName }} is provided by Link2Feed, and varies depending on the environment (Test, Live, Staging, etc) being accessed.

HTTP Method: POST to add, or PATCH to update

Request Headers: Authorization, Content-Type, Host, Signed-Headers, X-API-Key

Request Payload: JSON ObjectThis object has a variable number of fields, depending on the setup of the individual environment. The expected fields are listed in the data types API response as enabledFields. In general, a valid response to the Client Details API is also a valid request payload for the add/update API.