Problem Statement: API design for copy and upload has thus far been somewhat haphazard and it would be useful to make it more consistent. Additionally there are some deficiencies in some of the current APIs that need to be addressed. For example, the copy API currently looks something like this <pre> POST /pulp/api/v3/rpm/copy/ types=['package', 'modulemd'] </pre> The problem with this API is that it will be difficult to make it play nicely with filtering, which has yet to be implemented. The filtering use case is essentially "copy units for which metadata matches these filters, e.g. name=walrus and version>1.1.0". However, because different unit types have different metadata fields, allowing the user to specify filters while also allowing more than one type of content to be copied at once would be problematic because there's no good way to determine what filters should apply to what content types. Possibly it could be done, but it would probably not be a good idea. Therefore it is best that the "types" parameter be removed entirely. Sidenote: In various discussions we've mentioned the utility (and possibly necessity) of being able to have a group of tasks that are atomic and transactional together. Something like this could be applied here in order to replace this functionality (however, it is out of scope for this Story). Because we're currently specifying the type to be copied via the types parameter, we would therefore need to switch to having the content type be part of the endpoint itself, like so: <pre> POST /pulp/api/v3/rpm/package/copy/ </pre> This would also mirror the endpoints for "one-shot" upload which look like. <pre> POST /pulp/api/v3/rpm/package/upload/ </pre> And also make it look more like the endpoint for viewing content. Another example: The upload APIs of various plugins (including the RPM plugin) are split between two different forms: <pre> POST /pulp/api/v3/rpm/package/upload/ </pre> and <pre> POST /pulp/api/v3/content/rpm/packages/ </pre> The former is the "one-shot upload" form wherein a package content is created by uploading an RPM, and artifact created and the content metadata parsed from the artifact at the same time. The latter is traditional viewset upload wherein you're really intended to be providing all of the metadata as part of the request. Because the metadata is embedded inside the file itself, we have currently severely hacked this endpoint in order to hydrate the serializer from the file whose name is provided in the request. This duplicate API should probably be removed in favor of one-shot upload. It makes sense only on types where the metadata is provided by the user, not by parsing the artifact.