Lookup Constituent By Constituent ID (In addition to the System ID)
We have SOPs built around using the Constituent ID and it is locked on the constituent record, but can be seen and searched by. Would be great to use GET Constituent and use this ID as criteria.
@Halley. Re: "... the default search functionality does perform a "starts with" operation on the provided search_text", I don't think this is correct.
Constituent search currently returns records where search text is contained anywhere in the search fields, not just the start.
Eg, searching for "walter" with strict-search=true returns records with names, emails, addresses, etc with content such as "Walter", "Walters", "Lichtenwalter", "Swalters", "12walter34", etc.
Scenario I am in and why a GET by constituent ID would be beneficial...
We two-way sync information between our campus SIS and RaisersEdge NXT.
Everything on our campus revolves around a campus ID number (which NXT stores as Constituent ID...or lookup_id if using the API)
Since everything function off our campus ID, so does our list of records to sync each night
In the old REAPI, we could pull up the record with one call. With the new SkyAPI it takes multiple requests to pull up a record by the campus ID.
It would be beneficial to decrease the number of unnecessary calls. The Constituent ID field does not need to be immutable for GET routing, it only needs to be unique.
Note: I thought about storing the NXT ids on our campus SIS as an alternate ID to make the syncing easier, but since the old REAPI had this lookup by constituent ID before I would prefer to not lose functionality here.
@David, but isn't this is exactly what the REAPI allows with LoadByField? Ie, the ability to provide a field value and tell the loader what type of field you have passed (within a fixed selection of types). It was a god-send (small "g" ...) on many occasions for me.
Also, I've noticed that several endpoints in the FE API group provide the ability to retrieve, say, Transactions by Project UI ID (ui_project_id), rather than only by System ID.
So I'm confused as to why this seems to be such a sticking point with the SKY API.
@Steve I was referring to the fact that the REAPI is based around the system id and not the constituent id. It would not be practical to start referencing all constituents by the lookup code. This is especially the case when you are able to change constituent id / lookup id or indeed leave it blank.
@David, can you expand on your comment "The old REAPI has that same constraint ..."?
Do you mean that the Load method has to be a SysRec ID rather than a Constit ID?
I'm not sure why a separate endpoint similar to the REAPI's LoadByField can't be added if this is easier for Blackbaud. It would be flexible, clear, concise, targeted, narrow and very probably doesn't pack the back-end load punch of a generalized search (at a guess).
@Halley, can you expand on your comment "In route ids must be immutable"?
Why must they be immutable?
Provided this new functionality is guaranteed to return one and only one Constituent record, we can live with it as well.
Halley, this is sufficient for us. The old REAPI has the same constraint and it is very understandable why it has that. To be able to look up exactly by lookup id though is a definite winner.
Hey guys! Just adding an update here -- in short, we will not be adding the option to use lookup ID to all endpoints. In route ids must be immutable, which is why we use the system ids as the in route identifier. We are, however, about to release an update to the constituent search endpoint to allow for exact matching on lookup_id in addition to the current fuzzy search. This new query parameter will allow you to more effectively target the exact constituent you want based on their lookup_id to fetch their immutable constituent_id for use in future calls.
Additionally, for those of you asking for wildcard matching, the default search functionality does perform a "starts with" operation on the provided search_text. This means that if you supply "123," returned results will include "123," "1234," 123-4," etc. Granted, this will also include constituents who have addresses with that value at the current time, but we do intend to expand the available query parameters on this endpoint to more effectively and flexibly target your desired constituents.
I'd like to weigh in on this and vote for ability to query by "Lookup ID" of all endpoints with additional nuance that you can use wildcards. Our organization supports many nonprofit fraternity/sorority chapter alumni association groups in RE and one of two ways we distinguish our individual clients is by using the Lookup ID. For example, all of client group 123's member Lookup IDs are prefixed with "123-" (as in 123-1, 123-2,123-3). We also differentiate between clients by using constituent attribute codes (Category=Client Code; Value=123), but the contortions required to pull data we need with the Constituent API makes this entirely impractical (you can see my posts/ideas on this subject in forums/ideas). HOWEVER, the ability to GET by Lookup ID with wildcard (as in 123-*) would, I think allow us to find, count, and report on members JUST for that particular client website That wild card would need to allow the inclusion of the "-" as this is our delimiter between client id and our assigned member id. Thanks!
BTW, this seems to be similar to the (excellent!) RE7 API ability to LoadByField. (What a god-send that is!) It's available for a number of objects, including Constituents, Actions, Appeals, even Queries. (It's sadly missing from FE as far as I'm aware.)
In case your not familiar with it, here's a Constituent example:
Dim oCon as New CRecord oCon.Load(123) 'Loads the Constituent with System Record ID 123 oCon.LoadByField(bbRECORDUniqueFields.uf_Record_CONSTITUENT_ID, "123") 'Loads the Consit with Constituent ID = "123" oCon.LoadByField(bbRECORDUniqueFields.uf_Record_IMPORT_ID, "123") 'Loads the Consit with Import ID = "123" Etc.
So Blake's idea of specifying mode=lookup could easily be expanded with an id_type enumerated parameter. Eg GET /constituents/123?id_type=1|2|3|4|... where id_type 1 = Lookup ID, 2 = Import ID, 3 = Email Address, etc.
I like both ideas. I was picturing to at least be able to specify what I'd like to search by so I like your option of specifying the search text AND the search_type parameter. So I'd pass two parameters:
value=1234
search_type="lookup id" or search_type "Employee ID" to the search_type parameter.
That could return the "Constituent ID (aka System ID)" and I could use that in the GET /constituents/{constituent_id} approach.
That's fair. So are you looking more for the ability to specify what you'd like search to search by? So, for example, something like ?search_text=123&search_type=lookup_id ?
Or are you really looking for endpoints in which you can specify GET /constituents/{lookup_id} in addition to the current GET /constituents/{constituent_id} ?
I hope this is ok, but to clear up confusion I changed the title of this idea to "Lookup Constituent By Constituent ID (In addition to the System ID)". I am not asking to replace the use of the System ID, or change naming convention. I just want the ability to ALSO search specifically by Constituent ID, or specific alias types.
First off, I would like to thank you for this feedback. Changing constituent_id to just be idon the Constituent entity will definitely be a candidate for a future version of the API. If nothing else, that pattern is more consistent with our other entity types in which their system ID is simply called "id," like a couple of folks touched on in this thread. So that was a miss on our part/a remnant of an earlier iteration of the Constituent API.
I apologize for the confusion this has caused. Changing it now would unfortunately be too much of a wide sweeping change for all of our developers to introduce as a breaking change in the Constituent API today. But, we will update the documentation to be more explicit about it being the system ID in the immediate future, and will definitely make sure this is considered in the next Constituent API version we introduce.
I completely understand to use the System Record ID as primary since it can not be changed by anyone, but we use aliases for integration with our membership, HR and other systems. Since the Constituent ID is visible (and locked in DB view to our users), that has been our exposed ID for several years in reports, gift entry and general user interaction in the UI. When you search in the API by lookup ID the request searches the "Constituent ID" AND aliases, so I have some searches that return two+ constituents. For example, my own record has an alias for employee ID to match against our HR system. We also have a different constituent record whose db view Constituent ID happens to have the same value as my employee ID alias. I can not specify in the api lookup id search to use my employee ID only if the alias type is "Employee ID" (can I?).
The only way I see around this yet to be released feature is to maintain a lookup table externally and make calls against which requires a lot of other setup maintenance and risk. I'd rather my idea (or version like it) get approved.
+1 to Steve about getting tripped up by calling the System Record ID the "constituent_id" in the API call. I'm actually fine with using the system record id for calls and even naming it (oddly / counter-intuitively after a field name that already exists in the database view. However, I think you've [at least] got to surface/show the System Record ID on the constituent summary panel and make it available as an output field on lists in RE NXT. Do I need to cross post this idea to RE NXT ideas or is someone minding ideas for such overlaps?
Personally, I'm baffled by the idea of calling the System Record ID constituent_id and the Constituent ID lookup_id in the first place. It was the first thing I tripped over when I tried out our sandbox. And it's redundant to call it constituent_id when it's actually the unique id.
So the base call should really have been defined as GET /constituents/{id}.
Be that as it may, I second Brian's suggestion which I'd bet is faster than performing a search. It could even be expanded for use with, say, Import Id and to other endpoints such as Actions.
Seems to me that for any entity (not just constituent but gifts, etc.) that includes a lookup_id attribute we ought to have an endpoint available that can use that attribute to retrieve a record. Not much point in supporting something called a Lookup ID if you can't actually lookup by it with the API.
What if the endpoints that expect a System ID by default were modified to take an optional ?mode=<system/lookup> parameter? By default it continues to be have as-is but optionally the developer can specify that they wish to lookup by lookup_id instead?
So GET /constituents/1234 would behave exactly as it does now and return the Constituent with System ID 1234 but GET /constituents/ABCD?mode=lookup would return the Constituent with Lookup ID ABCD
This is a bit of a tricky one. Curious to get others' thoughts on it, as I see we have a few folks that have voted on it.
We're not likely to change the GET /constituents/{constituent_id} endpoint logic to use lookup_id (a.k.a., Constituent ID) instead of id (a.k.a., System ID).
The constituent search endpoint (GET /constituents/search?search_text={search_text}) supports matching constituents by lookup_id. Can people comment on the challenges and gaps here?
@Halley. Re: "... the default search functionality does perform a "starts with" operation on the provided search_text", I don't think this is correct.
Constituent search currently returns records where search text is contained anywhere in the search fields, not just the start.
Eg, searching for "walter" with strict-search=true returns records with names, emails, addresses, etc with content such as "Walter", "Walters", "Lichtenwalter", "Swalters", "12walter34", etc.
This was covered in a Community post a while back.
Scenario I am in and why a GET by constituent ID would be beneficial...
It would be beneficial to decrease the number of unnecessary calls. The Constituent ID field does not need to be immutable for GET routing, it only needs to be unique.
Note: I thought about storing the NXT ids on our campus SIS as an alternate ID to make the syncing easier, but since the old REAPI had this lookup by constituent ID before I would prefer to not lose functionality here.
@David, but isn't this is exactly what the REAPI allows with LoadByField? Ie, the ability to provide a field value and tell the loader what type of field you have passed (within a fixed selection of types). It was a god-send (small "g" ...) on many occasions for me.
Also, I've noticed that several endpoints in the FE API group provide the ability to retrieve, say, Transactions by Project UI ID (ui_project_id), rather than only by System ID.
So I'm confused as to why this seems to be such a sticking point with the SKY API.
@Steve I was referring to the fact that the REAPI is based around the system id and not the constituent id. It would not be practical to start referencing all constituents by the lookup code. This is especially the case when you are able to change constituent id / lookup id or indeed leave it blank.
@David, can you expand on your comment "The old REAPI has that same constraint ..."?
Do you mean that the Load method has to be a SysRec ID rather than a Constit ID?
I'm not sure why a separate endpoint similar to the REAPI's LoadByField can't be added if this is easier for Blackbaud. It would be flexible, clear, concise, targeted, narrow and very probably doesn't pack the back-end load punch of a generalized search (at a guess).
@Halley, can you expand on your comment "In route ids must be immutable"?
Why must they be immutable?
Provided this new functionality is guaranteed to return one and only one Constituent record, we can live with it as well.
Thanks, Steve
Halley, this is sufficient for us. The old REAPI has the same constraint and it is very understandable why it has that. To be able to look up exactly by lookup id though is a definite winner.
Hey guys! Just adding an update here -- in short, we will not be adding the option to use lookup ID to all endpoints. In route ids must be immutable, which is why we use the system ids as the in route identifier. We are, however, about to release an update to the constituent search endpoint to allow for exact matching on lookup_id in addition to the current fuzzy search. This new query parameter will allow you to more effectively target the exact constituent you want based on their lookup_id to fetch their immutable constituent_id for use in future calls.
Additionally, for those of you asking for wildcard matching, the default search functionality does perform a "starts with" operation on the provided search_text. This means that if you supply "123," returned results will include "123," "1234," 123-4," etc. Granted, this will also include constituents who have addresses with that value at the current time, but we do intend to expand the available query parameters on this endpoint to more effectively and flexibly target your desired constituents.
I'd like to weigh in on this and vote for ability to query by "Lookup ID" of all endpoints with additional nuance that you can use wildcards. Our organization supports many nonprofit fraternity/sorority chapter alumni association groups in RE and one of two ways we distinguish our individual clients is by using the Lookup ID. For example, all of client group 123's member Lookup IDs are prefixed with "123-" (as in 123-1, 123-2,123-3). We also differentiate between clients by using constituent attribute codes (Category=Client Code; Value=123), but the contortions required to pull data we need with the Constituent API makes this entirely impractical (you can see my posts/ideas on this subject in forums/ideas). HOWEVER, the ability to GET by Lookup ID with wildcard (as in 123-*) would, I think allow us to find, count, and report on members JUST for that particular client website That wild card would need to allow the inclusion of the "-" as this is our delimiter between client id and our assigned member id. Thanks!
BTW, this seems to be similar to the (excellent!) RE7 API ability to LoadByField. (What a god-send that is!) It's available for a number of objects, including Constituents, Actions, Appeals, even Queries. (It's sadly missing from FE as far as I'm aware.)
In case your not familiar with it, here's a Constituent example:
So Blake's idea of specifying mode=lookup could easily be expanded with an id_type enumerated parameter. Eg GET /constituents/123?id_type=1|2|3|4|... where id_type 1 = Lookup ID, 2 = Import ID, 3 = Email Address, etc.
I like both ideas. I was picturing to at least be able to specify what I'd like to search by so I like your option of specifying the search text AND the search_type parameter. So I'd pass two parameters:
That could return the "Constituent ID (aka System ID)" and I could use that in the GET /constituents/{constituent_id} approach.
That's fair. So are you looking more for the ability to specify what you'd like search to search by? So, for example, something like ?search_text=123&search_type=lookup_id ?
Or are you really looking for endpoints in which you can specify GET /constituents/{lookup_id} in addition to the current GET /constituents/{constituent_id} ?
I hope this is ok, but to clear up confusion I changed the title of this idea to "Lookup Constituent By Constituent ID (In addition to the System ID)". I am not asking to replace the use of the System ID, or change naming convention. I just want the ability to ALSO search specifically by Constituent ID, or specific alias types.
Hi everyone,
First off, I would like to thank you for this feedback. Changing constituent_id to just be id on the Constituent entity will definitely be a candidate for a future version of the API. If nothing else, that pattern is more consistent with our other entity types in which their system ID is simply called "id," like a couple of folks touched on in this thread. So that was a miss on our part/a remnant of an earlier iteration of the Constituent API.
I apologize for the confusion this has caused. Changing it now would unfortunately be too much of a wide sweeping change for all of our developers to introduce as a breaking change in the Constituent API today. But, we will update the documentation to be more explicit about it being the system ID in the immediate future, and will definitely make sure this is considered in the next Constituent API version we introduce.
Thanks,
Halley
There was a question about this that has some relevance to this. https://community.blackbaud.com/forums/viewtopic/426/36533
I posted this there.
I completely understand to use the System Record ID as primary since it can not be changed by anyone, but we use aliases for integration with our membership, HR and other systems. Since the Constituent ID is visible (and locked in DB view to our users), that has been our exposed ID for several years in reports, gift entry and general user interaction in the UI. When you search in the API by lookup ID the request searches the "Constituent ID" AND aliases, so I have some searches that return two+ constituents. For example, my own record has an alias for employee ID to match against our HR system. We also have a different constituent record whose db view Constituent ID happens to have the same value as my employee ID alias. I can not specify in the api lookup id search to use my employee ID only if the alias type is "Employee ID" (can I?).
The only way I see around this yet to be released feature is to maintain a lookup table externally and make calls against which requires a lot of other setup maintenance and risk. I'd rather my idea (or version like it) get approved.
+1 to Steve about getting tripped up by calling the System Record ID the "constituent_id" in the API call. I'm actually fine with using the system record id for calls and even naming it (oddly / counter-intuitively after a field name that already exists in the database view. However, I think you've [at least] got to surface/show the System Record ID on the constituent summary panel and make it available as an output field on lists in RE NXT. Do I need to cross post this idea to RE NXT ideas or is someone minding ideas for such overlaps?
Personally, I'm baffled by the idea of calling the System Record ID constituent_id and the Constituent ID lookup_id in the first place. It was the first thing I tripped over when I tried out our sandbox. And it's redundant to call it constituent_id when it's actually the unique id.
So the base call should really have been defined as GET /constituents/{id}.
Be that as it may, I second Brian's suggestion which I'd bet is faster than performing a search. It could even be expanded for use with, say, Import Id and to other endpoints such as Actions.
Seems to me that for any entity (not just constituent but gifts, etc.) that includes a lookup_id attribute we ought to have an endpoint available that can use that attribute to retrieve a record. Not much point in supporting something called a Lookup ID if you can't actually lookup by it with the API.
What if the endpoints that expect a System ID by default were modified to take an optional ?mode=<system/lookup> parameter? By default it continues to be have as-is but optionally the developer can specify that they wish to lookup by lookup_id instead?
So GET /constituents/1234 would behave exactly as it does now and return the Constituent with System ID 1234 but GET /constituents/ABCD?mode=lookup would return the Constituent with Lookup ID ABCD
This is a bit of a tricky one. Curious to get others' thoughts on it, as I see we have a few folks that have voted on it.
We're not likely to change the GET /constituents/{constituent_id} endpoint logic to use lookup_id (a.k.a., Constituent ID) instead of id (a.k.a., System ID).
The constituent search endpoint (GET /constituents/search?search_text={search_text}) supports matching constituents by lookup_id. Can people comment on the challenges and gaps here?