Showing results for 
Show  only  | Search instead for 
Did you mean: 
Community Participant

Mass Announcements with Embedded Images

I'm an admin in an ID + support role, but have been a back-end admin as well, so I play a few unique roles. One of my favorite things is playing around with the API. I'll start out by saying that this is something I want to share out as a solution to a problem that I encountered rather than a question -- if this isn't the right spot, feel free to move it appropriately.

I've been posting announcements en masse to courses for a variety of reasons -- special programs for subsets of courses, college-specific events, targeted assessment info for students, etc. However, I always made folks provide a PDF of their flyer or images because I couldn't figure out how to get images to post with the announcement since, normally, those images would reside within each course.

Turns out it's simpler than you'd think.

  1. In the Global Navigation Bar, click Account > Files.
  2. I recommend you create a new folder for assets if you plan to use this approach often.
  3. Name your file appropriately and upload it to your new folder.
  4. Go to a course, create a Page, embed the image, save the Page.
  5. Edit the page, go to the HTML view, copy the HTML of the embedded image, looks like this:
    <p><img id="5079330" src="https://[canvas_url]/users/[your_user_id]/files/[image_file_id]/preview?verifier=[redacted]" alt="descriptive text below image" data-api-endpoint="https://[canvas_url]/api/v1/users/[your_user_id]/files/[image_file_id]" data-api-returntype="File" /></p>​
  6. Paste that where you want it in the HTML for your mass announcement. I highly recommend utilizing a plain text editor or code editor (e.g., Atom) to compose your announcement and archiving them for later.

Here's what my sample looks like in Atom, what my Postman call looks like, and what the end result announcement looks like. Apologies for the links, I couldn't figure out how to embed these for the life of me (ironic, I know....). Hopefully this helps somebody, I know I've had a lot of requests to push announcements to large lists of classes -- the most recent one where I made this discovery was about 150 courses. This neat little trick makes life easy and lets you make announcements a little prettier.

P.S., I noticed that trying to utilize things like DIVs causes the API call to return a 500 error. No idea why and the message is cryptic. Kinda bummed about that, as you can definitely use DIVs in announcements, I guess you just can't send them in that parameter.

6 Replies
Community Member

The Postman POST string isn't completely visible. Could you additionally post that complete string as you did the HTML above? This is a gold mine. Thanks for posting it!

Community Participant

Hey @lgekeler since Postman concatenates all your values into the call, it's pretty much junk, but here it is cleaned up a little:


 The {{base_domain}} is just a collection variable that is replaced with the URL for my institution's Canvas instance within the Postman toolbox I've put together. For :course_id (copied directly from the Canvas Rest API documentation) I use another collection variable for my sandbox unless I'm running a CSV, in which case I use an unassigned variable in the same format such as {{course_id}} that matches the header of my CSV. Unsure how familiar you are with Postman, but figure if anybody else sees this in the future, overexplaining might help.

I can't express my frustration with the number of times I've found a "solution" that doesn't have enough information for me to act. Reach out if you still have questions!

Community Member

Thank you @bpoullio1 , this really helps. I am learning Postman little by little. I hope to be a pro by next spring {professional development goals, you know}. Stay tuned.

Community Participant

I understand 100% @lgekeler . Here's how I break down an API call from the Canvas documentation into Postman

  1. I use Collections. Easiest way for me to organize. In the collection I can set:
    1. Production and test domain URL variables
    2. Production/test API token variables
    3. Other useful variables (e.g., my sandbox course ID)
  2. I've started using folders because with the Postman Runner, where you can process a CSV list of many operations at once, you can run all operations in a folder for a given line in a CSV. This is helpful for semi-automating some processes. For example, I created a workflow to enroll a user in a past course that first sets a future end date, then enrolls the user in the specified section, then reverts the end date back to the original state. All with fairly simple API calls and no real programming.
  3. Collections can also house your Authorization setup. Set as Bearer Token and use your collection variable for prod or test token as default, change in an individual call if you're testing/moving to production.
  4. There are more complex things you can do like saving the results to a CSV -- there's a neat little script somebody wrote that doesn't work exactly like I need, but it does a great job of getting me 85% of the way there and cuts down on days of labor for our bookstore.

For the Canvas Rest API documentation, pick an API call and look at how it's written. It very closely matches Postman, it's just missing a few key elements.

Screen Shot 2021-10-13 at 3.14.42 PM.png

This tells you it's a GET request, that you can choose the "scope" (do you want all the enrollments within an entire course, just from a single section, or a user's list of enrollments), and what information you need in the form of an ID for course, section, or user. Choose the scope you want and copy from "/api..." through the end of the call. Go to Postman, create a new request in your Collection/Folder, make sure the HTTP method matches (GET in this case), and paste into the box that says "Enter the request URL".

Screen Shot 2021-10-13 at 3.28.28 PM.png

Now you should have something that looks like this, and notice that whatever scope you chose, the :scope_id changed into a path variable:

Screen Shot 2021-10-13 at 3.30.35 PM.png

Now go in and enter your Canvas URL or your Collection variable that represents it before "/api..." to complete the request URL. That's all you need to enter manually up top. The rest all goes in the Query Params section (for the most part). Look at the next section of the Canvas Rest API documentation and choose which query parameters you want to filter your request by. Some calls have a LOT, some have very few options. 

Screen Shot 2021-10-13 at 3.34.10 PM.png

Copy the parameter text (or type it exactly) and paste it into the column in Postman under Query Params where it says "Key".

Screen Shot 2021-10-13 at 3.38.47 PM.png

Now figure out values. Some are unique Canvas IDs, which are hard to figure out. The Object IDs page is the most useful thing I've stumbled across because I know what our SIS ID architecture is and can query based on that model very easily.

I'll stop there, but can share out more if you're interested. I love Postman, it has helped me grow from API-interested to API-obssessed!

Community Member

uh-oh. I think I've caught the bug! This has helped tremendously. Now I want to format my output, like, limit output to just some variables of the user enrollment data and eliminate the course_id information for course enrollments. This is fun. I hope to do some interesting things soon, but with Postman I think these things I want to do are things I need javascript for, aren't they?

Thank you so much for spending so much time putting this together. You rock @bpoullio1  !

Community Participant

Always happy to help! It can be intimidating, but it gets way easier when you have a few minutes to jump in. When you get towards wanting to manipulate the data you get back, you're moving into writing your own code. Doesn't require JS, you can pick your poison on that front. I like my Python, but if you're more comfortable with something else, go that route. Postman actually has a way to export a code snippet to make your API call when you've polished it up, which is really awesome. Keep pushing, feel free to message me!