First of all: I would like to provide what I believe is the reason that most types of objects cannot have an imgsrc with marketplace URLs. In general, imgsrc must be the URL of an img within our own Roll20 library, and the stated reason for this, at least according to the wiki , is " in order to provide safety to all Roll20's users". In addition, I believe the restriction on Roll20 Marketplace URLs in createObj exists to prevent unauthorized sharing of paid content — the existing framework perhaps cannot easily verify whether a given Roll20 Marketplace URL belongs to a purchase owned by the API caller. My request is for you to i ntroduce the following new global function that API scripts can call within the sandbox: copyObj(TYPE, ID[, ATTRIBUTES]) Creates a direct copy of the Roll20 Obj that would be found with getObj(TYPE, ID) , with the only thing changing between the original and the copy being things like _id which must be unique. If ATTRIBUTES is provided, they will be used to override the values on the copy at the time of creation. NOTE: This copies ALL properties of the Roll20 Obj identified by TYPE + ID , including imgsrc and sides , both of which would normally involve URL verification. Parameters: TYPE (String): the _type of the Roll20 object to be copied. This is the same parameter that would be passed into getObj . ID (String): the _id of the Roll20 object to be copied. This is the same parameter that would be passed into getObj . ATTRIBUTES (Standard JS object, optional): A normal javascript object with attributes for values that should be used in the copy instead of the corresponding values in the original Roll20 object. NOTE: If values within ATTRIBUTES are set to invalid values, or set to values that violate the rules set forth by createObj (such as imgsrc URLs that do not belong to the API caller's Roll20 Library), the object will fail to be copied (just as it would fail with createObj ). This means if the user wants to copy an object with a marketplace URL, they must NOT set the imgsrc in the ATTRIBUTES argument object. Returns: The Roll20 object that was created as a copy. Examples: // Simple copy of a token (exact duplicate on same page, same position, etc.) var copy = copyObj ( 'graphic' , tokenId ); // Copy a marketplace token (the key use case — imgsrc is preserved) // Currently impossible with createObj because marketplace URLs are rejected var clone = copyObj ( 'graphic' , marketplaceTokenId , { _pageid : pageId , left : 400 , top : 400 }); // Copy a handout var source = findObjs ({ type : 'handout' , name : 'Monster Stats' })[ 0 ]; var duplicate = copyObj ( 'handout' , source . get ( 'id' ), { name : 'Copy of ' + source . get ( 'name' ) }); // Copy an entire page (just the page object, not the objects on it) // A separate copyPageAndObjs function to essentially mirror the // "Duplicate" UI button for pages would be nice, but is a separate issue var newPage = copyObj ( 'page' , pageId , { name : 'New Page Name' }); // copyObj should fail for any object type that would fail with createObj, // such as 'campaign' or 'player' var campaign = copyObj ( 'campaign' , Campaign (). get ( 'id' )); // logs error and returns undefined var player = copyObj ( 'player' , playerId ); // logs error and returns undefined // copyObj also fails for attribute overrides that would fail with createObj var badObj = copyObj ( 'graphic' , tokenId , { name : '<a href="https://disallowed.com/thumb.png?12345678" rel="nofollow">https://disallowed.com/thumb.png?12345678</a>' }); // logs error and returns undefined Addressing Concerns: How does this address the security concerns (or potential marketplace thievery concerns, or any other concerns related to the url issue)? Since copyObj requires its first two arguments to be identifiers (type, id) there is no way for a user to "hack" their way into providing an invalid object. The original object MUST exist in the campaign and if it exists in the campaign, then any imgsrc for that object MUST by definition be in someone's library OR purchased on the marketplace. In other words, the safety of the copyObj function is guaranteed by the security measures of createObj . Doesn't the user already have a native way to copy objects (i.e. copy/paste, or the Duplicate button for pages, handouts, etc.)? Yes, the user has this functionality already, but it is manual. If a plugin wishes to automate this process for something larger and more complex (as I would like to do), then this would be a game changer. What about allowing marketplace URLs in createObj ? This opens a vector for injecting arbitrary marketplace URLs that the user doesn't own. The copyObj function is scoped by nature, only allowing copies of things that are already in the campaign and therefore already owned by one of the users in said campaign.