How to copy YouTube annotations
TL;DR: Use this website.
Hello.
This weekend I had the need to copy YouTube annotations from one video to several other videos. After a lot of ideas that did not work I finally found a solution that worked quite beautifully. Eureka!
You first download the annotations in an XML format that YouTube uses internally. The url goes something like this: http://www.google.com/reviews/y/read2?video_id=X&username=Y&auth_token=Z&owner=1×tamp=&draft=1. You can get the auth_token by looking at the source of the “edit annotations” page.
Now that you have liberated your annotations data, you have to upload it to your other video. First get the auth_token of your destination video. You now have to edit your XML to fit a new format that is used when submitting new annotation data. First update the video_id value in the requestHeader tag. Then add this tag just below the requestHeader tag: <authenticationHeader timestamp="" owner="1" auth_token="Z" username="Y" />. Then rename the annotations tag to updatedItems. The XML file should now be ready for submission.
Now upload the new XML file as POST data to this url: http://www.google.com/reviews/y/update2. Make sure you are logged into the account that owns the destination video. Now voila! The new annotations have been saved as a draft. Just go to the “edit annotations” page and press Publish!
Okay, the above sounds very complicated, but I have of course made a website with client-side JavaScript which makes it very easy. You can use it to to copy the annotations to several videos at once very quickly.
Take a moment to think about the importance of having control over your own data. Google is thinking about this if you look at their Data Liberation site. But annotations data is something they haven’t gotten around to yet.
Anyway… there you go. Happy copying!
Be sure to leave a kind comment if this helped you.
Edit: The urls have changed in a recent update. The latest code is on the script page.

This is really great, unfortunately most videos are different lengths and end-times, meaning the annotation source code that is being copied wont really work on videos of varying lengths. (If I have an annotation on the last 30 seconds of every video, I can’t really copy the same annotation source code to multiple videos of varying lengths, I have to search and replace the end time of the source code for every video.) Is there a way you could design a way to insert the video length for each video next to the video id : Auth token, so that annotations at the end of the video would be copied easily between many videos of varying lengths? If you could this would be the greatest tool of all time
Hello.
I won’t add any functionality like that. The purpose of this post was to liberate and copy your annotations data. Manipulating the data can be done, and should be done, separate from this process. My aim is not to invent a new annotations editor.
For your particular case, you would have to code something which can accept the video length and manipulate a few annotations based on that. I suggest that you copy my code and edit it on your own.
Good luck!
Thanks for the response. Yea I can understand that, and for liberating our data this is perfect. Would you know of any tools out there that could mass edit YouTube descriptions easily? (ie. pull in video data based on ID and then send a post to update the descriptions / title / tags? I know there is a whole dedicated API site that youtube has but I have yet to find a solid script/tool that could do this in browser / GUI interface. ANy pointers would be helpful. Thanks again for this script!!
I don’t know any specifics. Additionally, I would suspect that the official YouTube API would only allow such access to your own videos.
luhl …. of course.. Im not trying to edit other peoples videos ; )
But you might want to copy them.
This is pretty incredible. I have been looking every where for something like this with no luck until I found you. I’m trying to simplify this by removing the interface. As an exercise I am trying use only the “function update()” to send the POST. I have figured out how to eliminate the need for the “username” and “id” fields by inserting them directly (var video_id = ‘myVideoID’;) I thought it would be just as simple to do with the data variable, but its proving to be over my head. I tried (var data = new XML(“myXMLdataHere”) that doesn’t do the trick. Is there a special way of formatting the XML? Any help would be really great. You have already helped me a ton with this post. Thnks
The code you posted should work, but you may have problems with newlines (which should be escaped with “\”). And you’ll have lots of ” inside the xml data which also needs to be escaped. Remember to check the error console, which will tell you about these errors!
Note that you can also put raw xml data (
var data = <document><requestHeader video_id="X" /><authenticationHeader timestamp="" owner="1" auth_token="Z" username="Y" />...</document>;) without usingnew XML("..."). This should be more convenient.Read more about XML processing here: https://developer.mozilla.org/En/E4X/Processing_XML_with_E4X
I figured out how to make it work the way I wanted, but now I have a much bigger problem. The annotations show up in the editor but not on the video. The annotations I add with this method can’t even be changed in the editor. Have you had this issue? I really need to find a fix for this.
They are only saved as a draft, so you have to press the publish button for them to be showed on the video page. I have no clue why you can’t edit the annotations, I have never encountered this.
Even when I press publish they don’t show. If I add an annotation manually, only the manually added one shows up. It could possibly be because I’m using XML from one channel to add annotations to my other channel. I replace the user name but, it could be the annotation Id stopping them from working.
I have changed every variable I can think of in the XML and it still only works on the channel the XML data came from. I changed the annotation id= to a random number expecting that was the problem. It still works on the original channel but not any of the others. How does youtube know where the XML came from?
I have never copied annotations across channels so I’m afraid you are on your own. Please post here if you solve the problem, it might be helpful for others. Good luck!
P.S. Maybe this is related to the multiple author feature that exists for annotations? You know, the link that you can send to others. Make sure you are logged in with the correct user on YouTube when updating your video.
I am not familiar with a multiple author feature. I just went searching and didn’t return anything. could you elaborate/tell me where to find this?
It is called collaborative annotations, and allows you to send a link to others so that they can add annotations to your video. I can’t seem to find it now so they must have disabled the feature. Here is the blog post when they announced it: http://youtube-global.blogspot.com/2009/02/introducing-collaborative-annotations.html
Stefan this is really exciting. I just wanted to know that is there any standard format used for saving annotations? Do other websites and annotating softwares also use XML for saving annotations?
No, I think this is a proprietary format created by Google. I don’t think there has been any attempt to standardize any format for annotations. I don’t even know if there are any other video service that have annotations except for YouTube.
<Shameless Plug>
http://www.AutoAnnotate.com
The website lets you copy an annotation from any of your videos and paste it on some or all of your other videos. You no longer have to do it by hand.
</Shameless Plug>
@AutoAnnotate.com
Wow. What an incredibly cheap advertisement. Do you really think you will be able to build a business on this?
Now if you’ll excuse me, I’ll clean up your comment a bit.
@recover Just want to say you have no idea how awesome this was for me to find your post, thank you so much for the explanation and the script. Anyway, I am in no way affiliated with whoever did that shameless plug, but I can tell you I’d absolutely pay a reasonable price for a service that does what your script or AutoAnnotate can do. I have a full-time job, and a gaming channel that I upload a ton of videos for all the time. I have some home-grown tools I made with the YouTube API for keeping up with vid info (title, description, keywords), but have never found anything for annotations. I had 3000+ vids before a channel reboot this past July, to make my channel copyright-friendly and monetize-able (just recently was able to monetize… time to get serious lol). I spend hourrrrrrrs every week trying to copy annotations that provide navigation links to other content on my channel. Before finding your post, I was seriously contemplating ditching my annotations, even though they provide nearly 15% of my views, because they take so much effort to keep up with. Now… with either your script or AutoAnnotate… trivial. Just sayin’
For people who have a lot of content on YT, a tool like this could be a game-changer as far as time spent maintaining vids. Thanks again for the info and script.
@pheedbaq
Well, you know. There’s always the donate button.
Hmm, can’t get it to work. I seem to be having the same issue as Patrick did back in April, only I’m copying from/to the same channel while logged in to my account. I can see the annotations are associated with the video I want them to be, because after I update using the script, I download the annotations and they’re in the download. However, they don’t show up on the vid or “edit annotations” page. If I add one manually through the YT interface, it shows up on the vid and on the edit page as normal, but not in the downloaded annotations list. If I delete all but one annotation from the xml I want to upload, and change the annotation id to some random number, it still doesn’t show up on the vid or in the edit list, but it does show up in the downloaded list as an additional entry along with all the others.
It seems to me the most likely cause is that annotations are no longer updated/added through http://www.google.com/reviews/y/update2, at least for a segment of the YT population… maybe there’s an update3 url??
@recover That AutoAnnotate service doesn’t work either. It seems to be having the same problem, doesn’t see annotations I’ve added recently. I think YT has just changed something altogether.
@pheedbaq
Haven’t used my script in a long time. I’ll investigate.
@pheedbaq
YouTube has indeed changed the URLs. The new URLs are http://www.youtube.com/annotations_auth/update2 and similar. I would assume that the data you got were simply copies from their old database (and any change there wasn’t reflected in the new database).
Anyway, I have updated all my scripts now (and also made it look nicer). So everything should be fine now. Let me know if you encounter any problems.
Awesome. I was able to update annotations, but only if “publish” was left unchecked. I copied your code and changed it so that the if(publish) block defines a separate xhr_pub as its XmlHttpRequest object, thinking maybe it was the two asynchronous calls getting in the way of each other somehow because of whacky timing or queuing in the js engine or something. That allowed the annotations to update when publish was checked, but even then they still don’t publish. Not that I’m complaining mind you
This will already save me hours and hours of work, as I typically have upwards of 10 annotations per vid that just need copying. Donation on the way, sir!
BTW I also tried splitting off the publish code into its own function, and created a separate Publish button, on the off chance FireFox’s js interpreter does some black magic for multiple asynchronous calls in the same function… lol, didn’t work. It was a shot in the dark anyway :\
@pheedbaq Why, thank you very much sir.
I will take a look at that publish code. It worked when I tested it before.
@pheedbaq I spent some more time on the script. You no longer have to touch the XML if you simply want to copy the annotations, so the instructions are simplified. The technical details are still available if you look in the source code.
I also moved the publish stuff to a separate button. You are probably right that the previous approach was flawed due to the nature of asynchronous requests. Just press this one after you press Update and you are set to go.
I have been having a bad time with Firefox too. The reason is that XML manipulation is really poorly implemented, and some features that are described in their documentation simply does not work, and you can’t use all the DOM manipulation methods either. In a sense the Chrome team made a good call to not even try to support E4X. Mozilla has also abandoned future improvements to E4X. Hopefully everyone starts using JSON soon.
Awesome
Publishing works now too! Thanks!
Just found out that you can grab the annotations for any video as XML from http://www.youtube.com/annotations/read2?video_id=$ID
hope it helps someone, if not, please ignore
@CBiX I was aware of urls looking like this: http://www.youtube.com/annotations_auth/read2?video_id=X, but not the url you posted. After further investigation it seems that it only uses “/annotations_auth/” if you are the owner of the video, otherwise just “/annotations/”. Thanks for sharing.
Hey recover, i searched alot for these “auth_token”s… what are these? And is that safe to send/use them?
Greets from Germany
@sebastian Hello. Auth tokens are automatically generated tokens that grant the owner of that token certain privileges. In this case updating annotations data for YouTube videos. You automatically use them when you edit your YouTube annotations (even though you don’t see it).
I would not share them with other people if I were you. Even if you would, the access you give other people is time-limited. I don’t know if they are usable in other places other than annotations data.
@recover Thank you! Am I right, if i say that the process of sending the XML as Post-Data to Youtube is the same process which happens if I press the “Save” – Button before I publish the Annotations? If this would be, Youtube would have no possibility (i think so) to check if i use a own script AND it would be 100% sure, isn’t it? Or is there a mistake?
@sebastian Don’t assume that YouTube can’t detect this. But would they bother? No, they wouldn’t. So don’t worry about that.
@recover
)
That’s good! So i will make a little script which will automaticaly change my annoations.. 5 Minutes boring work, just in a few seconds
And because i do not send information to another page than youtube, the script will be save, i hope so? (or did i overlook something?; i really dont want to lose my channel
And my last question:
@sebastian Unless you share the key with anyone else, you’re completely safe. And yes, using the script should be exactly the same as pressing Save in the annotations editor. You can use Firebug to compare the two.
Okay, thank you! My script works
Works great except the Greasemonkey script doesn’t make the auth_token show up. I have to manually get the HTML source code and search for the auth_token to get it.
Also, on Apple computers, it’s Apple+Shift+J to open the Error Console. I’m on an iMac.
@Jesse Smith It broke with YouTube’s redesign. Fixed now. Thanks for letting me know.
This is a badass tool. My only gripe is that I have to copy and paste every single VideoId:AuthCode instead of bulk copy all of them once (I made an iMacros that autoextract all of them from my hundreds of YT videos
).
Did you make this on purpose to avoid overloading your server? Eventually am I allowed to copy the code and run it on my server? What part should I modify to make possible a bulk copy of VideoId:AuthCode lines (I’m pretty sure is very easy, it’s just that I’m a sort of coding goat, lol)?
Thanks a lot!
@LittleSantaHelper No, that’s not on purpose. My server is not involved at all when you copy annotations. It’s just that I never ran into the case of having a bunch of video_id:auth_tokens in the same text field.
What you should do is edit the code so that you put video_id:auth_tokens in a <textarea>. Then make the submit code split on newlines and loop through them. And yes, you can download the html file and modify it at will, since it does not depend on anything else. For a donation I can do this work for you.
Good luck!
I’m absolutely willing to donate to have that mod done
Is it ok a 25$ donation? You can then send me the code to my Paypal email.
@LittleSantaHelper Okay, I’ve updated the script. Let me know if you miss anything. I also added instructions on how to delete annotations while I was at it. Enjoy.
You can find a paypal button if you press the “Projects” tab at the top of my blog. You decide the amount. Thank you for donating, it’s very much appreciated!
P.S. It would be nice if you could share your iMacros script so others can use it too.
Just tested with one hundred videos, and damn, that was FAST!
As promised, the donation is on its way
About the iMacros script, as soon as I get the permission from a forum user that wrote the Regex part (as stated before I’m not that programming savvy and I look for help wherever I can
), I’ll share it here!
Me too on a way to get hold of all my auth_tokens in one go, I like the idea of changing my annotations all in one go – it doesnt seem possible to get those from a gdata xml request. Any other ways to do it other than the iMacros?
@Nick You could try adapting my greasemonkey script to collect all the auth_tokens in one go. I could do this for you in return of a donation.
@recover
I’d love to be able to grab them all then update annotations in one process.
Do the auth_tokens expire? Or can you collect a list once then keep using it and update when you add a new video?
@recover
And yes, happy to donate in return for that.
@Nick Sorry for the delay. I have updated the script now. Simply update it and navigate to youtube.com/my_videos and look at the bottom of the page. If you have very many videos you might have to go to each page manually.
As you might see the auth_tokens look very much alike. I would guess that the current time is used together with some other value to calculate the auth_token, and these requests are made during the same second or two, so thus they get almost identical auth_tokens. This is a new discovery. To make it easier for you to identify which line correspond to which video, the video title is added to the end of the line (this is ignored by the copy script, so you can include the title when using that script too, and it will just ignore it).
To answer your question, I think the auth_tokens expire, but I have not verified this. Feel free to experiment.
Let me know if this works good or if you want me to tweak something. Good luck.
~Hi mate, nicely done, though I’m not entirely clear which script to update – if its the Greasemonkey one, It doesnt seem to let me, do you have a url to the new one?
Thanks, looking forward to testing
I just figured it out, now where do we donate?
@Nick There’s a donate link in the Projects tab at the top. Thank you.
Also, let me know if you need me to tweak anything.
@Nick I still haven’t received a donation.
I have found another cool trick you can do with annotations. If you insert a pause annotation at the very end that is 0.1s long, it will cause the video to automatically repeat (example). It’s a really cool bug.
Hej Stefan. Forsokte skriva till dig men kunde inte hitta nagon email pa siten. Men jag kanner mig lite mosig idag sa jag kanske bara missat den. Jag antar att du ser min email? Kan du skriva till mig? Jag vill garna prata lite om denna tool.
Sry non-scandinavians. This was a scandi thing of no interest to you