以下のような URL で、ブランチやタグとジョブ名を指定して最新のアーティファクトから特定のファイルを取得できます。
https://example.com/projects/:id/jobs/artifacts/:ref_name/raw/*artifact_path?job=name https://example.com/<namespace>/<project>/-/jobs/artifacts/<ref>/raw/<path_to_file>?job=<job_name>
しかし、あくまでも passed となった最新のパイプラインのアーティファクトが取得されるため、下記のように when: manual と allow_failure: false を使って手動ジョブで後続のジョブをブロックしていると、build が終わってパイプラインが blocked となった時点ではまだこのアーティファクトは取得できません。手動ジョブをすべて実行してパイプラインが passed になったタイミングでアーティファクトが取得できます。
stages: - build - deploy/stage - deploy/prod build: stage: build script: - env | grep CI | sort > env.txt artifacts: paths: - env.txt expire_in: 10 days deploy/stage: stage: deploy/stage when: manual allow_failure: false script: - echo ok deploy/prod: stage: deploy/prod when: manual allow_failure: false script: - echo ok

次のように allow_failure: false がなければ手動ジョブが未実行でもパイプラインは passed となるため、手動ジョブが未実行でも build ジョブのアーティファクトが取得できます。
stages: - build - deploy/stage - deploy/prod build: stage: build script: - env | grep CI | sort > env.txt artifacts: paths: - env.txt expire_in: 10 days deploy/stage: stage: deploy/stage when: manual script: - echo ok deploy/prod: stage: deploy/prod when: manual script: - echo ok

ただ、when: manual なジョブの後段に when: manual ではないジョブがあるとき、前段のジョブが未実行でも後段のジョブが実行されてしまいます。

下記のようにジョブIDを指定するAPIを使えば blocked なパイプラインのアーティファクトも取れますが、ブランチ名やタグ名からジョブIDを取得する簡単な方法はなさそう(パイプラインやジョブのリストからフィルタするしかなさそう)。
https://example.com/projects/:id/jobs/:job_id/artifacts/*artifact_path
さいごに
パイプラインを when: manual で止めて、前段のアーティファクトを Gitlab の外であれこれ検証したうえで手動ジョブを実行して後続のジョブを実行、みたいなことをしていたのですが、手動ジョブを allow_failure: false にしたら↑の通りアーティファクトがうまく取れなくなりました。
アーティファクトはジョブID指定で取るとかしないとだめですね。