Advocacy API -- having trouble accessing
So I am trying to use the server side advocacy API detailed here
http://open.convio.com/api/apidoc/Convio_Open_API_Reference.pdf
getAdvocacyAlerts (p43)
I am using the same server side proxy code that works fine on our community registration pages (which checks with the Constituent API for existing email addresses).
http://community.sierraclub.org/join/climatecrossroads.aspx
The user that does this is the same, and I have granted the API users group permission to be able to access the Advocacy API.
I am trying it on the same server (so I know the IP address range is fine):
http://community.sierraclub.org/convio-action-proxy.aspx
But I keep getting the same "Authorization Failed" error.
Anything else that I might be doing wrong here?
Thanks,
Adrian
Comments
-
Your API Administrator account must belong to a security group that has the Advocacy API permission. This information will be included in the Advocacy API docs due to be published later in the week.
0 -
Steve Mook:
Your API Administrator account must belong to a security group that has the Advocacy API permission. This information will be included in the Advocacy API docs due to be published later in the week.
Oops, read right past the fact that you've already set Advocacy API permission. I'll check with the developer...
0 -
Steve Mook:
Oops, read right past the fact that you've already set Advocacy API permission. I'll check with the developer...
Thanks, any additional info would be great, Steve.
0 -
Adrian Cotter:
Thanks, any additional info would be great, Steve.
You'll also get this error if the login_name and login_password parameters are passed in the URL, as opposed to the body of a server API HTML request. Have you tried enabling logging under Setup/Site Options/Open API Configuration?
0 -
Steve Mook:
You'll also get this error if the login_name and login_password parameters are passed in the URL, as opposed to the body of a server API HTML request. Have you tried enabling logging under Setup/Site Options/Open API Configuration?
I have done the logging, but I cannot see what additional information it is giving me. I see the requests, it's not telling me why they are rejected -- as far as I can tell (actually it doesn't even seem to say they were rejected either). What should I be looking for?
As to the username and password in the body -- I am submitting the request in the same way I was doing with the ConstituentAPI to check for duplicate email (which is working fine). This is what the code looks more or less like (hopefully the vb code will make some sense even if you don't know VB offhand...):
Dim oRequest As HttpWebRequest = CType(WebRequest.Create("https://secure2.convio.net/sierra/site/SRAdvocacyAPI"), HttpWebRequest)
oRequest.Method = "POST"
SubmitString &= "&login_name=***"
SubmitString &= "&login_password=***"
SubmitString &= "&api_key=***"
SubmitString &= "&v=1.0"
SubmitString &= "&response_format=json"
SubmitString &= "&method=getAdvocacyAlerts"
SubmitString &= "&list_page_size=20"
SubmitString &= "&alert_status=ACTIVE"
SubmitString &= "&alert_type=ACTION"
Dim bytePostData As Byte() = System.Text.Encoding.GetEncoding(1252).GetBytes(SubmitString)
oRequest.ContentLength = bytePostData.Length
oRequest.ContentType = Request.ContentType
'--actually sending the data over HTTP to our catch page
Dim strPostData As Stream = oRequest.GetRequestStream()
strPostData.Write(bytePostData, 0, bytePostData.Length)
strPostData.Close()
'--reading the response from the HTTP Post
Dim oResponse As WebResponse = oRequest.GetResponse()
Dim enc As Encoding = Encoding.GetEncoding(1252)
Dim sr As StreamReader = New StreamReader(oResponse.GetResponseStream(), enc)
Dim s As String = sr.ReadToEnd
sr.Close()
Response.Write(s)0 -
Adrian Cotter:
I have done the logging, but I cannot see what additional information it is giving me. I see the requests, it's not telling me why they are rejected -- as far as I can tell (actually it doesn't even seem to say they were rejected either). What should I be looking for?
As to the username and password in the body -- I am submitting the request in the same way I was doing with the ConstituentAPI to check for duplicate email (which is working fine). This is what the code looks more or less like (hopefully the vb code will make some sense even if you don't know VB offhand...):
Dim oRequest As HttpWebRequest = CType(WebRequest.Create("https://secure2.convio.net/sierra/site/SRAdvocacyAPI"), HttpWebRequest)
oRequest.Method = "POST"
SubmitString &= "&login_name=***"
SubmitString &= "&login_password=***"
SubmitString &= "&api_key=***"
SubmitString &= "&v=1.0"
SubmitString &= "&response_format=json"
SubmitString &= "&method=getAdvocacyAlerts"
SubmitString &= "&list_page_size=20"
SubmitString &= "&alert_status=ACTIVE"
SubmitString &= "&alert_type=ACTION"
Dim bytePostData As Byte() = System.Text.Encoding.GetEncoding(1252).GetBytes(SubmitString)
oRequest.ContentLength = bytePostData.Length
oRequest.ContentType = Request.ContentType
'--actually sending the data over HTTP to our catch page
Dim strPostData As Stream = oRequest.GetRequestStream()
strPostData.Write(bytePostData, 0, bytePostData.Length)
strPostData.Close()
'--reading the response from the HTTP Post
Dim oResponse As WebResponse = oRequest.GetResponse()
Dim enc As Encoding = Encoding.GetEncoding(1252)
Dim sr As StreamReader = New StreamReader(oResponse.GetResponseStream(), enc)
Dim s As String = sr.ReadToEnd
sr.Close()
Response.Write(s)Here is a simple form that works against my test box. If it works for you we need to look more closely at the VB code, otherwise we probably have a server configuration issue.
<html>
<body>
<form method="POST" action="https://secure2.convio.net/sierra/site/SRAdvocacyAPI">
method: <input type="text" name="method" value="getAdvocacyAlerts" /><br />
api_key: <input type="text" name="api_key" value="api_key" /><br />
v: <input type="text" name="v" value="1.0" /><br />
login_name: <input type="text" name="login_name" value="api_admin" /><br />
login_password: <input type="text" name="login_password" value="api_admin" /><br />
alert_status: <input type="text" name="alert_status" value="ACTIVE" /><br />
alert_type: <input type="text" name="alert_type" value="ACTION" /><br />
list_page_size: <input type="text" name="list_page_size" value="20" /><br />
<input type="submit" value="Send" />
</form>
</body>
</html>0 -
Adrian Cotter:
I have done the logging, but I cannot see what additional information it is giving me. I see the requests, it's not telling me why they are rejected -- as far as I can tell (actually it doesn't even seem to say they were rejected either). What should I be looking for?
As to the username and password in the body -- I am submitting the request in the same way I was doing with the ConstituentAPI to check for duplicate email (which is working fine). This is what the code looks more or less like (hopefully the vb code will make some sense even if you don't know VB offhand...):
Dim oRequest As HttpWebRequest = CType(WebRequest.Create("https://secure2.convio.net/sierra/site/SRAdvocacyAPI"), HttpWebRequest)
oRequest.Method = "POST"
SubmitString &= "&login_name=***"
SubmitString &= "&login_password=***"
SubmitString &= "&api_key=***"
SubmitString &= "&v=1.0"
SubmitString &= "&response_format=json"
SubmitString &= "&method=getAdvocacyAlerts"
SubmitString &= "&list_page_size=20"
SubmitString &= "&alert_status=ACTIVE"
SubmitString &= "&alert_type=ACTION"
Dim bytePostData As Byte() = System.Text.Encoding.GetEncoding(1252).GetBytes(SubmitString)
oRequest.ContentLength = bytePostData.Length
oRequest.ContentType = Request.ContentType
'--actually sending the data over HTTP to our catch page
Dim strPostData As Stream = oRequest.GetRequestStream()
strPostData.Write(bytePostData, 0, bytePostData.Length)
strPostData.Close()
'--reading the response from the HTTP Post
Dim oResponse As WebResponse = oRequest.GetResponse()
Dim enc As Encoding = Encoding.GetEncoding(1252)
Dim sr As StreamReader = New StreamReader(oResponse.GetResponseStream(), enc)
Dim s As String = sr.ReadToEnd
sr.Close()
Response.Write(s)Maybe I'm mistaken, but shouldn't it look like this (note the lack of an ampersand before the first query string):
SubmitString &= <span style="color:#FF0000;">"login_name=***"</span><br />SubmitString &= <span style="color:#FF0000;">"&login_password=***"</span><br />SubmitString &= <span style="color:#FF0000;">"&api_key=***"</span><br />SubmitString &= <span style="color:#FF0000;">"&v=1.0"</span><br />SubmitString &= <span style="color:#FF0000;">"&response_format=json"</span><br />SubmitString &= <span style="color:#FF0000;">"&method=getAdvocacyAlerts"</span><br />SubmitString &= <span style="color:#FF0000;">"&list_page_size=20"</span><br />SubmitString &= <span style="color:#FF0000;">"&alert_status=ACTIVE"</span><br />SubmitString &= <span style="color:#FF0000;">"&alert_type=ACTION"</span>
0 -
Noah Cooper:
Maybe I'm mistaken, but shouldn't it look like this (note the lack of an ampersand before the first query string):
SubmitString &= <span style="color:#FF0000;">"login_name=***"</span><br />SubmitString &= <span style="color:#FF0000;">"&login_password=***"</span><br />SubmitString &= <span style="color:#FF0000;">"&api_key=***"</span><br />SubmitString &= <span style="color:#FF0000;">"&v=1.0"</span><br />SubmitString &= <span style="color:#FF0000;">"&response_format=json"</span><br />SubmitString &= <span style="color:#FF0000;">"&method=getAdvocacyAlerts"</span><br />SubmitString &= <span style="color:#FF0000;">"&list_page_size=20"</span><br />SubmitString &= <span style="color:#FF0000;">"&alert_status=ACTIVE"</span><br />SubmitString &= <span style="color:#FF0000;">"&alert_type=ACTION"</span>
So I tried the form (with my admin user, password, api key etc) and got:
<errorResponse xsi:schemaLocation="http://convio.com/crm/v1.0 http://service.convio.net/xmlschema/crm.public.v1.xsd">
<code>1</code>
<message>Unable to process request.</message>
</errorResponse>Noah,
As to your point, it's true that the ampersand is not necessary, but it doesn't make a difference whether the & is there or not (and I tried ? there for kicks as well to no avail).
0 -
Adrian Cotter:
So I tried the form (with my admin user, password, api key etc) and got:
<errorResponse xsi:schemaLocation="http://convio.com/crm/v1.0 http://service.convio.net/xmlschema/crm.public.v1.xsd">
<code>1</code>
<message>Unable to process request.</message>
</errorResponse>Noah,
As to your point, it's true that the ampersand is not necessary, but it doesn't make a difference whether the & is there or not (and I tried ? there for kicks as well to no avail).
Just to be certain, about the user and all, I also tried the constituent API with a similar form, and got an appropriate response back... I'll send you a message with the form URL.
0 -
Adrian Cotter:
Just to be certain, about the user and all, I also tried the constituent API with a similar form, and got an appropriate response back... I'll send you a message with the form URL.
On the one hand your form seems to be getting past the authorization error. I think the VB script may work as well, but you may be getting back a cached result from before you added the necessary permission. I find that even with the form, I will continue to get back a success or authorization failure result even after changing the API Administrator group permissions as long as I continue to use the same API admin login. Adding another admin account and switching between them when I change group permissions clears whatever is being cached to cause that.
On the other hand, the form seems to have uncovered a bug. We are looking at a stack trace for the "Unable to process request" error now.
0 -
Steve Mook:
On the one hand your form seems to be getting past the authorization error. I think the VB script may work as well, but you may be getting back a cached result from before you added the necessary permission. I find that even with the form, I will continue to get back a success or authorization failure result even after changing the API Administrator group permissions as long as I continue to use the same API admin login. Adding another admin account and switching between them when I change group permissions clears whatever is being cached to cause that.
On the other hand, the form seems to have uncovered a bug. We are looking at a stack trace for the "Unable to process request" error now.
Thanks Steve, let me know what you find out. I'd love to have this working for a couple of projects.
0 -
Adrian Cotter:
Thanks Steve, let me know what you find out. I'd love to have this working for a couple of projects.
Adrian,
The bug that's causing the second error is triggered by Alerts which were associated with Advocacy Issues that have since been deleted. I just saw a fix come through and will try to find out the release target for it. Currently the only work-around is to go into the affected Alert(s) and edit the Interests list, which will clean up the bad cross-references. However, short of directly querying the database, there isn't an easy way to tell which Alerts those are.
Thanks for helping us track this down.
Steve
0 -
Steve Mook:
Adrian,
The bug that's causing the second error is triggered by Alerts which were associated with Advocacy Issues that have since been deleted. I just saw a fix come through and will try to find out the release target for it. Currently the only work-around is to go into the affected Alert(s) and edit the Interests list, which will clean up the bad cross-references. However, short of directly querying the database, there isn't an easy way to tell which Alerts those are.
Thanks for helping us track this down.
Steve
Thanks Steve, glad you all were able to track down the bug.
So I see now that if I change the page list size and offset I can sometimes get results (list_offset_record=0 and page_size=12 work fine, the 13 record seems to be a problem).
Two Questions then:
How are the alerts ordered? It might help me to track down knowing which alerts are the problem if I knew the order they were being displayed. I can't quite tell from what I am seeing stepping through them one by one (it's not by alert ID, or date published for instance). The documentation doesn't say as far as I can tell.
Also for list_page_offset and list_record_offset, do those begin with 1 or 0? Seems like 0, but just want to be certain (also would be good to note in the documentation).
0 -
Yes, the list offset is 0-based. Thanks for the tip on documentation, I will add that.
getAdvocacyAlerts returns a filtered but theoretically unordered SQL result set. There is likely a practical ordering, but it may not be a very useful one.
0 -
Steve Mook:
Yes, the list offset is 0-based. Thanks for the tip on documentation, I will add that.
getAdvocacyAlerts returns a filtered but theoretically unordered SQL result set. There is likely a practical ordering, but it may not be a very useful one.
Oof. So that kind of means if I wanted to find the latest published alert (for instance), I'd have to walk through the whole set (I mean to do some processing on our server anyway and save off a local copy, but it means some extra work).
The other thing I'd love to see is the ability to filter by security category. It's more consistently used than issues.
0 -
Steve Mook:
Adrian,
The bug that's causing the second error is triggered by Alerts which were associated with Advocacy Issues that have since been deleted. I just saw a fix come through and will try to find out the release target for it. Currently the only work-around is to go into the affected Alert(s) and edit the Interests list, which will clean up the bad cross-references. However, short of directly querying the database, there isn't an easy way to tell which Alerts those are.
Thanks for helping us track this down.
Steve
Hey Steve,
Any word when the fix will be in? The error is still occurring for me.
Also any concrete info on the ordering would be appreciated... I can't make heads or tails of it, and I'm having trouble figuring out how to use in a practical way without doing a lot of extra work.
Thanks,
Adrian
0 -
Adrian Cotter:
Hey Steve,
Any word when the fix will be in? The error is still occurring for me.
Also any concrete info on the ordering would be appreciated... I can't make heads or tails of it, and I'm having trouble figuring out how to use in a practical way without doing a lot of extra work.
Thanks,
Adrian
Adrian,
The bug fix is scheduled to be published in the next patch update, which is currently in test; I will let you know as soon as it is available.
Data returned by the current version of the API is unordered; if you need it in a particular order you have to sort it. I did note your earlier suggestions as enhancement requests for a future version update, and passed those on to the product manager.
Steve
0 -
Steve Mook:
Adrian,
The bug fix is scheduled to be published in the next patch update, which is currently in test; I will let you know as soon as it is available.
Data returned by the current version of the API is unordered; if you need it in a particular order you have to sort it. I did note your earlier suggestions as enhancement requests for a future version update, and passed those on to the product manager.
Steve
Adrian, the fix for this bug is in the 6.2.1 patch scheduled to go live Wednesday night. It should be available Thursday 3/11.
0 -
Thanks Steve... just so that anyone who stumbles across this thread sees the note at the bottom:
"The fix for this bug (some alerts breaking the feed, where the alert had been connected to deleted issues) is in the 6.2.1 patch scheduled to go live Wednesday night.
It should be available Thursday 3/11/10."
0 -
finally coming back to this API. Things looking better, but still some problems
I'm trying to sort the responses using the new list_sort_column but it is not working as far as I can tell. This is my GET statement
response_format=xml&alert_status=ACTIVE&alert_type=ACTION&list_page_size=5&list_page_offset=0&list_sort_column=alertId&list_ascending=false
I cannot get list_sort_column doesn't matter if I include _ascending or not, or what I sort on, I get the alerts back in the same order?
Could be my site is not using the latest API, or am I making some other mistake here...
http://community.sierraclub.org/convio-action.htm
Thanks!
Adrian
0 -
Adrian Cotter:
finally coming back to this API. Things looking better, but still some problems
I'm trying to sort the responses using the new list_sort_column but it is not working as far as I can tell. This is my GET statement
response_format=xml&alert_status=ACTIVE&alert_type=ACTION&list_page_size=5&list_page_offset=0&list_sort_column=alertId&list_ascending=false
I cannot get list_sort_column doesn't matter if I include _ascending or not, or what I sort on, I get the alerts back in the same order?
Could be my site is not using the latest API, or am I making some other mistake here...
http://community.sierraclub.org/convio-action.htm
Thanks!
Adrian
list_sort_column is newly supported in the Advocacy API as of the Summer 2010 release, which your site doesn't have yet. That's the issue. One other thing to note is that alert_status and alert_type must be lowercase as of the Summer release.
0 -
Noah Cooper:
list_sort_column is newly supported in the Advocacy API as of the Summer 2010 release, which your site doesn't have yet. That's the issue. One other thing to note is that alert_status and alert_type must be lowercase as of the Summer release.
Thanks Noah. I did look to see if it was represented a particular release or not.
It would be great if the documentation noted what release the text was good for, and that you could get to older versions while they are still in use.
0
Categories
- All Categories
- Shannon parent
- shannon 2
- shannon 1
- 21 Advocacy DC Users Group
- 14 BBCRM PAG Discussions
- 89 High Education Program Advisory Group (HE PAG)
- 28 Luminate CRM DC Users Group
- 8 DC Luminate CRM Users Group
- Luminate PAG
- 5.9K Blackbaud Altru®
- 58 Blackbaud Award Management™ and Blackbaud Stewardship Management™
- 409 bbcon®
- 2.1K Blackbaud CRM™ and Blackbaud Internet Solutions™
- donorCentrics®
- 1.1K Blackbaud eTapestry®
- 2.8K Blackbaud Financial Edge NXT®
- 1.1K Blackbaud Grantmaking™
- 527 Education Management Solutions for Higher Education
- 1 JustGiving® from Blackbaud®
- 4.6K Education Management Solutions for K-12 Schools
- Blackbaud Luminate Online & Blackbaud TeamRaiser
- 16.4K Blackbaud Raiser's Edge NXT®
- 4.1K SKY Developer
- 547 ResearchPoint™
- 151 Blackbaud Tuition Management™
- 61 everydayhero
- 3 Campaign Ideas
- 58 General Discussion
- 115 Blackbaud ID
- 87 K-12 Blackbaud ID
- 6 Admin Console
- 949 Organizational Best Practices
- 353 The Tap (Just for Fun)
- 235 Blackbaud Community Feedback Forum
- 55 Admissions Event Management EAP
- 18 MobilePay Terminal + BBID Canada EAP
- 36 EAP for New Email Campaigns Experience in Blackbaud Luminate Online®
- 109 EAP for 360 Student Profile in Blackbaud Student Information System
- 41 EAP for Assessment Builder in Blackbaud Learning Management System™
- 9 Technical Preview for SKY API for Blackbaud CRM™ and Blackbaud Altru®
- 55 Community Advisory Group
- 46 Blackbaud Community Ideas
- 26 Blackbaud Community Challenges
- 7 Security Testing Forum
- 3 Blackbaud Staff Discussions
- 1 Blackbaud Partners Discussions
- 1 Blackbaud Giving Search™
- 35 EAP Student Assignment Details and Assignment Center
- 39 EAP Core - Roles and Tasks
- 59 Blackbaud Community All-Stars Discussions
- 20 Blackbaud Raiser's Edge NXT® Online Giving EAP
- Diocesan Blackbaud Raiser’s Edge NXT® User’s Group
- 2 Blackbaud Consultant’s Community
- 43 End of Term Grade Entry EAP
- 92 EAP for Query in Blackbaud Raiser's Edge NXT®
- 38 Standard Reports for Blackbaud Raiser's Edge NXT® EAP
- 12 Payments Assistant for Blackbaud Financial Edge NXT® EAP
- 6 Ask an All Star (Austen Brown)
- 8 Ask an All-Star Alex Wong (Blackbaud Raiser's Edge NXT®)
- 1 Ask an All-Star Alex Wong (Blackbaud Financial Edge NXT®)
- 6 Ask an All-Star (Christine Robertson)
- 21 Ask an Expert (Anthony Gallo)
- Blackbaud Francophone Group
- 22 Ask an Expert (David Springer)
- 4 Raiser's Edge NXT PowerUp Challenge #1 (Query)
- 6 Ask an All-Star Sunshine Reinken Watson and Carlene Johnson
- 4 Raiser's Edge NXT PowerUp Challenge: Events
- 14 Ask an All-Star (Elizabeth Johnson)
- 7 Ask an Expert (Stephen Churchill)
- 2025 ARCHIVED FORUM POSTS
- 322 ARCHIVED | Financial Edge® Tips and Tricks
- 164 ARCHIVED | Raiser's Edge® Blog
- 300 ARCHIVED | Raiser's Edge® Blog
- 441 ARCHIVED | Blackbaud Altru® Tips and Tricks
- 66 ARCHIVED | Blackbaud NetCommunity™ Blog
- 211 ARCHIVED | Blackbaud Target Analytics® Tips and Tricks
- 47 Blackbaud CRM Higher Ed Product Advisory Group (HE PAG)
- Luminate CRM DC Users Group
- 225 ARCHIVED | Blackbaud eTapestry® Tips and Tricks
- 1 Blackbaud eTapestry® Know How Blog
- 19 Blackbaud CRM Product Advisory Group (BBCRM PAG)
- 1 Blackbaud K-12 Education Solutions™ Blog
- 280 ARCHIVED | Mixed Community Announcements
- 3 ARCHIVED | Blackbaud Corporations™ & Blackbaud Foundations™ Hosting Status
- 1 npEngage
- 24 ARCHIVED | K-12 Announcements
- 15 ARCHIVED | FIMS Host*Net Hosting Status
- 23 ARCHIVED | Blackbaud Outcomes & Online Applications (IGAM) Hosting Status
- 22 ARCHIVED | Blackbaud DonorCentral Hosting Status
- 14 ARCHIVED | Blackbaud Grantmaking™ UK Hosting Status
- 117 ARCHIVED | Blackbaud CRM™ and Blackbaud Internet Solutions™ Announcements
- 50 Blackbaud NetCommunity™ Blog
- 169 ARCHIVED | Blackbaud Grantmaking™ Tips and Tricks
- Advocacy DC Users Group
- 718 Community News
- Blackbaud Altru® Hosting Status
- 104 ARCHIVED | Member Spotlight
- 145 ARCHIVED | Hosting Blog
- 149 JustGiving® from Blackbaud® Blog
- 97 ARCHIVED | bbcon® Blogs
- 19 ARCHIVED | Blackbaud Luminate CRM™ Announcements
- 161 Luminate Advocacy News
- 187 Organizational Best Practices Blog
- 67 everydayhero Blog
- 52 Blackbaud SKY® Reporting Announcements
- 17 ARCHIVED | Blackbaud SKY® Reporting for K-12 Announcements
- 3 Luminate Online Product Advisory Group (LO PAG)
- 81 ARCHIVED | JustGiving® from Blackbaud® Tips and Tricks
- 1 ARCHIVED | K-12 Conference Blog
- Blackbaud Church Management™ Announcements
- ARCHIVED | Blackbaud Award Management™ and Blackbaud Stewardship Management™ Announcements
- 1 Blackbaud Peer-to-Peer Fundraising™, Powered by JustGiving® Blogs
- 39 Tips, Tricks, and Timesavers!
- 56 Blackbaud Church Management™ Resources
- 154 Blackbaud Church Management™ Announcements
- 1 ARCHIVED | Blackbaud Church Management™ Tips and Tricks
- 11 ARCHIVED | Blackbaud Higher Education Solutions™ Announcements
- 7 ARCHIVED | Blackbaud Guided Fundraising™ Blog
- 2 Blackbaud Fundraiser Performance Management™ Blog
- 9 Foundations Events and Content
- 14 ARCHIVED | Blog Posts
- 2 ARCHIVED | Blackbaud FIMS™ Announcement and Tips
- 59 Blackbaud Partner Announcements
- 10 ARCHIVED | Blackbaud Impact Edge™ EAP Blogs
- 1 Community Help Blogs
- Diocesan Blackbaud Raiser’s Edge NXT® Users' Group
- Blackbaud Consultant’s Community
- Blackbaud Francophone Group
- 1 BLOG ARCHIVE CATEGORY
- Blackbaud Community™ Discussions
- 8.3K Blackbaud Luminate Online® & Blackbaud TeamRaiser® Discussions
- 5.7K Jobs Board